home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 095 / rbbssrc2.arc / RBBSSUB2.BAS < prev   
Encoding:
BASIC Source File  |  1987-03-15  |  145.4 KB  |  3,767 lines

  1. ' $linesize:132
  2. ' $title: 'RBBSSUB2.BAS CPC15-1A, Copyright 1986 & 87 by D. Thomas Mack'
  3. '  Copyright 1987 by D. Thomas Mack, all rights reserved.
  4. '  Name ...............: RBBSSUB2.BAS
  5. '  Written by .........: D. Thomas Mack
  6. '  First Released .....: June 29, 1986
  7. '  Subsequent Releases.: September 28, 1986, March 15, 1987
  8. '  Copyright ..........: 1986, 1987
  9. '  Purpose.............: The Remote Bulletin Board System for the IBM PC,
  10. '                        RBBS-PC.BAS utilizes a lot of common subroutines.
  11. '                        Those that do not reqpure error trapping are
  12. '                        incorporated within RBBSSUB2.BAS as separately call-
  13. '                        able subroutines in order to free up as much code as
  14. '                        possible within the 64K code segment used by
  15. '                        RBBS-PC.BAS.
  16. '  Parameters..........: Most parameters are passed via a COMMON statement.
  17. '
  18. ' Subroutine  Line               Function of Subroutine
  19. '   Name     Number
  20. '  ALLCAPS    58060   Convert a string to all upper case characters
  21. '  ALLCAPSD   58065   Convert a dimensioned string to all upper case characters
  22. '  AMORPM     41500   Calculate the current time as AM or PM
  23. '  BADCHAR      455   Check user name for invalid characters
  24. '  BADFILE    20741   Check for system crash attempt with bad device name
  25. '  BADNAME    20235   Check for system crash attempt with bad file name
  26. '  BRKFNAME   20282   Break a file name into it's component parts
  27. '  BUFFILE    58400   Write a file to the user quickly
  28. '  BUFSTRNG   58300   Write a string with imbedded CR/LF to the user quickly
  29. '  CALLOPT    58090   Set prompts based on the user's security
  30. '  CARRIER    42000   Test for Carrier present
  31. '  CHECKTIM   58070   Test to insure that users don't exceed their time
  32. '  CHKNARY    58180   Check for the occurance of a string in an array
  33. '  CHKNEWBUL  58110   Check for new bulletins based on their file creation date
  34. '  COMMINFO   44000+  Get users baud rate and parity in a string format
  35. '  COMPDATE   59200+  Produces a computational data from YY, MM, DD
  36. '  CONVDIRS   58950   Checks for U & A (shorthand) and converts appropriately
  37. '  COPYWRIT      97   Display RBBS-PC's copyright notice
  38. '  CTNEWFILES 58150   Check for number of files uploaded after a specific date
  39. '  CTLINES    58160   Find the number of entries in the upload management sys.
  40. '  DEFALTU     9600   Write out the user's defaults
  41. '  DELAYIT    50500   Wait number of seconds specified before returning
  42. '  DISPLAYTR  41010+  Compute and display time remaining
  43. '  DISUPDIR   58170   Display the upload directory of the upload mng. sys.
  44. '  DOOREXIT   10987   Set up a .BAT file to exit RBBS-PC and go to a "door"
  45. '  DOSEXIT    10934   Set up a .BAT file to exit to DOS (second level)
  46. '  FILELOCK   21995   Allow files to be shared among multiple RBBS-PC's
  47. '  FINDFUNC   58040   Find the function key, if any, that was depressed
  48. '  FINDLAST   58600   Finds last occurence of a string in a string
  49. '  FINDTIME   58050   Calculate the number of seconds since midnight
  50. '  FMS        58200   Search the upload management system for entries
  51. '  GETCOMND      97+  Get RBBS-PC's node id from command line
  52. '  GETDIRS    58900   Prompts for directories for file list/new/search cmds
  53. '  GETIME      9140   Calculates callers elapsed time (hours, minutes, seconds)
  54. '  GETYMD     59200   Pulls YY, MM, or DD from a 2 byte stored date
  55. '  GRAPHIC    43031   Determines whether graphic version of file exists
  56. '  HASHRBBS   58080   "Hash" to a user's record in the USERS file
  57. '  HELP        1330   Processes help command
  58. '  INSCOMMA   58130   Format commands in the command prompt
  59. '  INITFMS    58160+  Initialize the managment upload system
  60. '  KILLMSG     3955   Delete old or unnecessary messages
  61. '  LINE25       949   Build and/or update line 25 of RBBS-PC's local screen
  62. '  LOADNEW    58140   Find the latest uploads
  63. '  LOGERROR   13660   Log error message to CALLERS file
  64. '  MLINIT        50   Handle MultiLink initialization/de-initialization
  65. '  MODEMPUT   52070   Write a modem command string to the modem
  66. '  MUSIC      59100   Play musical themes for different RBBS functions
  67. '  OPENMSG    30500   Open the messages file as file number 1
  68. '  PROTOCOL   62600   Determine if external protocols are available
  69. '  PRTCRLF     1478   Write "snoop" lines that may have imbedded CR/LF's
  70. '  QTPUT       1477   Fast, but limited, "TPUT" equivalent
  71. '  RBBSEXIT   10992   Common RBBS-PC exit to transfer control to other programs
  72. '  READPROF   44000   Read user's profile on return from a "door"
  73. '  RECOVMSG   10410   Recover a deleted message
  74. '  REMOVE     58210   Remove characters from within strings
  75. '  ROTORSDIR  58700   Searches for a file using list of subdirs
  76. '  SAVEPROF   43070   Save the user's provile when exiting to "doors" or DOS
  77. '  SETBAUD     1654   Set baud rate in the 8250 chip of the RS232 interface
  78. '  SETCRLF     1496   Set up the necessary carriage return/line feed string
  79. '  SETOPTS    58100   Set correct prompt line for each subsystem
  80. '  SKIPLINE    1485   Write a # of blank lines to the communications port
  81. '  SRCHCMND    1240   Searches list of commands in RBBS for a request
  82. '  SRTSTRNG   58120   Sort characters in a string
  83. '  SYSMENU      112   Displays sysop menu/status
  84. '  TIMEREMAIN 41010   Compute time remaining in minutes
  85. '  TRANSFER   62620   RBBS-PC support for external protocols for file transfer
  86. ' TWOBYTEDATE 59200   Reduces a data to 2 byte string for space compression
  87. '  UNTILRIGHT 12880   Ask a question until user say answers is right
  88. '  UPDATEU    10600   Updates the user record on loging off/exiting RBBS-PC
  89. '  UPDTUPLOAD 20705   Updates upload directory file
  90. '  VIEWARC    64600   Display .ARC file contents to user
  91. '  WILDCARD   20285   Determines whether string matches a pattern
  92. '  WIPELINE   58800   Wipes away a line so next prints in its place
  93. '  WORDINFILE 10976   Find a whole word within a file/menu
  94. '
  95. '  $INCLUDE: 'RBBS-VAR.BAS'
  96. '
  97. '  $SUBTITLE: 'MLINIT - MultiLink initialization/deinitialization'
  98. '  $PAGE
  99. '
  100. '  SUBROUTINE NAME    -- MLINIT
  101. '
  102. '  INPUT PARAMETERS   --  MLPARM = 1             INITIALIZE AT STARTUP OR RE-
  103. '                                                CYLCE TIME
  104. '                         MLPARM = 2             DE-INITIALIZE ON EXITING TO
  105. '                                                A DOOR OR DOS REMOTELY
  106. '                         MLPARM = 3             DE-QUEUE COMMUNICATIONS PORTS
  107. '                         MLPARM = 4             CHECK FOR MULTILINK PRESENT
  108. '                         DOORS.TERMINAL.TYPE
  109. '                         BAUD.TEST
  110. '                         COM.PORT$
  111. '                         COMPUTER.TYPE
  112. '
  113. '  OUTPUT PARAMETERS  --  NONE
  114. '
  115. '  SUBROUTINE PURPOSE --  TO TEST FOR THE PRESENCE OF MULTI-LINK AND SET
  116. '                         MULTI LINK OPTIONS TO BE COMPATIBLE WITH RBBS-PC
  117. '
  118.       SUB MLINIT (MLPARM) STATIC
  119.     DEF SEG = 0
  120.     IF COMPUTER.TYPE = 1 _
  121.        GOTO 10
  122.     IF NOT MLCOM THEN _
  123.        IF NETWORK.TYPE <> 1 THEN _
  124.           GOTO 10
  125.     MULTI.LINK.PRESENT = PEEK(&H1FE) + 256*PEEK(&H1FF)
  126.     IF MULTI.LINK.PRESENT = 0 THEN _
  127.        GOTO 10
  128.     ON MLPARM GOSUB 30,20,60,10
  129. 10  DEF SEG
  130.     EXIT SUB
  131. 20  IF DOORS.TERMINAL.TYPE < 1 THEN _
  132.        RETURN
  133.     DEF SEG = MULTI.LINK.PRESENT
  134.     GOSUB 60
  135. '
  136. ' *****************************************************************************
  137. ' *                  MLUTIL BAUD n (where n = BAUD.TEST)                      *
  138. ' *****************************************************************************
  139. '
  140.     AX = &H600
  141.     BX = BAUD.TEST   ' Tell ML the baud rate
  142.     GOSUB 80
  143. '
  144. ' *****************************************************************************
  145. ' *                  MLUTIL TERM n (where n = DOORS.TERMINAL.TYPE)            *
  146. ' *****************************************************************************
  147. '
  148.     AX = &H700 + DOORS.TERMINAL.TYPE
  149.     GOSUB 80         ' Tell ML the terminal type
  150. '
  151. ' *****************************************************************************
  152. ' *                  MLINK /port                                              *
  153. ' *****************************************************************************
  154. '
  155. '                    ' Tell ML the communications port
  156.     POKE (&H64+PEEK(&H58)+256*PEEK(&H59)+&HC),ASC(RIGHT$(COM.PORT$,1))-48
  157. '
  158. ' *****************************************************************************
  159. ' *                  MLUTIL SCMON                                             *
  160. ' *****************************************************************************
  161. '
  162.     AX = &HB01
  163.     BX = 0           ' Tell ML to start monitoring the carrier
  164.     GOSUB 80
  165.     RETURN
  166. '
  167. ' *****************************************************************************
  168. ' *                  MLUTIL CCMON                                             *
  169. ' *****************************************************************************
  170. '
  171. 30  AX = &HB00       ' Turn off ML's carrier monitoring.
  172.     BX = 0
  173.     GOSUB 80
  174. '
  175. ' *****************************************************************************
  176. ' *                  MLUTIL TERM 1                                            *
  177. ' *****************************************************************************
  178. '
  179.     AX = &H701       ' Change terminal type to ML type 1.
  180.     BX = 0
  181.     GOSUB 80
  182. '
  183. ' *****************************************************************************
  184. ' *                  MLINK /port (where port = 9 if ML 3.03 or earlier        *
  185. ' *                                     port = 0 if ML 4.00 or greater        *
  186. ' *****************************************************************************
  187. '
  188.     DEF SEG = MULTI.LINK.PRESENT
  189.     MULTI.LINK.COM.PORT = (&H64 + PEEK(&H58) + 256*PEEK(&H59) + &HC)
  190.     MULTI.LINK.VERSION = PEEK(&H1) + 256*PEEK(&H2)
  191.     IF PEEK(MULTI.LINK.COM.PORT) = &H1 OR &H2 THEN _
  192.        IF MULTI.LINK.VERSION > 5000 THEN _
  193.           POKE (MULTI.LINK.COM.PORT),&H0 _
  194.        ELSE POKE (MULTI.LINK.COM.PORT),&H9
  195. '
  196. ' *****************************************************************************
  197. ' *                  MLUTIL ENQ                                               *
  198. ' *****************************************************************************
  199. '
  200.     AX = &H1        ' Tell ML to conditional enque on the comm. port
  201.     GOSUB 70
  202. '
  203. ' *****************************************************************************
  204. ' *                  MLUTIL BAUD 19200                                        *
  205. ' *****************************************************************************
  206. '
  207.     AX = &H600       ' Tell ML to reset the buad rate (19200 BAUD)
  208.     BX = 19200
  209.     GOSUB 80
  210.     RETURN
  211. '
  212. ' *****************************************************************************
  213. ' *                  MLUTIL DEQ                                               *
  214. ' *****************************************************************************
  215. '
  216. 60 AX = &H100        ' Tell ML to unconditionally deque the comm. port
  217. 70 BX = -4
  218.    IF COM.PORT$ = "COM2" THEN _
  219.       BX = -3
  220. '
  221. ' *****************************************************************************
  222. ' *  MULTI-LINK PROGRAMMING SUPPORT INTERFACE                                 *
  223. ' *****************************************************************************
  224. '
  225. 80 CALL RBBSML(AX,BX)
  226.    RETURN
  227.    END SUB
  228. '  $SUBTITLE: 'COPYWRIT - subroutine to display RBBS-PC copyright'
  229. '  $PAGE
  230. '
  231. '  SUBROUTINE NAME    -- COPYWRIT
  232. '
  233. '  INPUT PARAMETERS   --  NONE
  234. '
  235. '  OUTPUT PARAMETERS  --  NONE
  236. '
  237. '  SUBROUTINE PURPOSE --  TO DISPLAY RBBS-PC'S COPYRIGHT NOTICE ON THE LOCAL
  238. '                         SYSOP'S SCREEN
  239. '
  240.       SUB COPYWRIT STATIC
  241. 97 WIDTH 80
  242.    CLS
  243.    KEY OFF
  244.    LOCATE ,,0
  245.    PRINT TAB(60)"tm"
  246.    PRINT TAB(16) STRING$(15,205)" U S E R W A R E " STRING$(15,205)
  247.    PRINT
  248.    PRINT TAB(17)"Capital PC User Group User-Supported Software"
  249.    PRINT
  250.    PRINT TAB(5) CHR$(214) STRING$(66,196) CHR$(183)
  251.    FOR I = 1 TO 12
  252.      READ A$
  253.      PRINT TAB(5) CHR$(186);A$; SPACE$(66 - LEN(A$)); CHR$(186)
  254.    NEXT
  255.    PRINT TAB(5) CHR$(211) STRING$(66,196) CHR$(189)
  256.    PRINT TAB(21)"Copyright (c) 1983-87 Tom Mack, 10210 Oxfordshire Road, Great Falls, VA"
  257.    DATA "    If you are using RBBS-PC CPC15.1 and find it valuable, I"
  258.    DATA "    suggest you consider a contribution to"
  259.    DATA ""
  260.    DATA "                 Capital PC Software Exchange"
  261.    DATA "                     Post Office Box 6128"
  262.    DATA "                Silver Spring, Maryland  20906"
  263.    DATA ""
  264.    DATA "    You are free to copy and share RBBS-PC CPC15.1 with"
  265.    DATA "    others on these three conditions:"
  266.    DATA "      1.  This program is not distributed in modified form."
  267.    DATA "      2.  No fee or consideration is charged for RBBS-PC, itself."
  268.    DATA "      3.  This notice is not bypassed or removed."
  269.    CALL DELAYIT (8)
  270.    END SUB
  271. ' $SUBTITLE: 'GETCOMND - subroutine to get command from command line'
  272. ' $PAGE
  273. '
  274. '  SUBROUTINE NAME    -- GETCOMND
  275. '
  276. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  277. '                        COMMAND LINE         COMMAND LINE USED TO INVOKE
  278. '                                             RBBS-PC IN THE FORM:
  279. '
  280. '                                             RBBS-PC.EXE x filename
  281. '
  282. '                                             WHERE:
  283. '
  284. '                                             x IS THE NODE ID IN THE RANGE
  285. '                                             1-9,0,A-Z AND filename IS THE
  286. '                                             FULLY QUALIFIED FILE NAME TO
  287. '                                             USE AS THE ".DEF" FILE.  THIS
  288. '                                             SECOND PARAMETER IS OPTIONAL.
  289. '                        CONFIG.FILENAME$     NAME OF RBBS-PC ".DEF" FILE TO
  290. '                                             USE AS A MODEL WHEN CREATING THE
  291. '                                             .DEF FILE NAME TO BE USED BY THIS
  292. '                                             COPY OF RBBS-PC.
  293. '
  294. '  OUTPUT PARAMETERS  -- CONFIG.FILENAME$     NAME OF RBBS-PC ".DEF" FILE FOR
  295. '                                             THIS COPY OF RBBS-PC TO USE
  296. '                        NODE.RECORD.INDEX    RECORD NUMBER WITHIN THE
  297. '                                             MESSAGES FILE FOR THIS "NODE"
  298. '                                             (RANGE IS 2 TO 36)
  299. '
  300. '  SUBROUTINE PURPOSE --  TO GET NODE ID FROM COMMAND LINE
  301. '
  302.       SUB GETCOMND (PASSED.DEBUG) STATIC
  303.       STATIC DEBUG
  304. '
  305. ' *****************************************************************************
  306. ' *  GET NODE ID FROM COMMAND LINE                                            *
  307. ' *****************************************************************************
  308. '
  309.       PM$ = COMMAND$
  310.       CALL ALLCAPS(PM$)
  311. 98    A = INSTR(PM$,"DEBUG")
  312.       IF A>0 THEN _
  313.          DEBUG = -1 : _
  314.          PM$ = LEFT$(PM$,A-1) + RIGHT$(PM$,LEN(PM$)-A-4)
  315.       PASSED.DEBUG = DEBUG
  316.       IF LEN(PM$) = 0 THEN _
  317.          PM$ = "-"
  318.       NODE.RECORD.INDEX = INSTR("-1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ",LEFT$(PM$,1))
  319.       IF NODE.RECORD.INDEX < 2 THEN _
  320.          NODE.RECORD.INDEX = 2
  321.       NODE.ID$ = STR$(NODE.RECORD.INDEX-1)
  322.       IF LEN(PM$) > 2 AND MID$(PM$,2,1) = " " THEN _
  323.          CONFIG.FILENAME$ = MID$(PM$,3)_
  324.       ELSE MID$(CONFIG.FILENAME$,5,1) = PM$
  325.       END SUB
  326. '
  327. '  $SUBTITLE: 'SYSMENU - subroutine to display RBBS-PC SYSOP menu'
  328. '  $PAGE
  329. '
  330. '  SUBROUTINE NAME    --  SYSMENU
  331. '
  332. '  INPUT PARAMETERS   --  PARAMETER           MEANING
  333. '                           DELAY!    TIME IN SECONDS AFTER MIDNIGHT TO WAIT
  334. '                                     BEFORE DISPLAYING
  335. '
  336. '  OUTPUT PARAMETERS  --  NONE
  337. '
  338. '  SUBROUTINE PURPOSE --  TO DISPLAY RBBS-PC's SYSOP MENU ON THE LOCAL SCREEN
  339. '
  340.     SUB SYSMENU STATIC
  341.     DELAY! = 0
  342. 112 LOCAL.USER = TRUE
  343.     SNOOP = TRUE
  344.     PAGE.LENGTH.HOLD = PAGE.LENGTH
  345.     PAGE.LENGTH = 0
  346.     SUBROUTINE.PARAMETER = 1
  347.     WHILE SUBROUTINE.PARAMETER = 1
  348.       CALL CHECKTIM (DELAY!)
  349.     WEND
  350.     CLS
  351.     BYPASS.TIME.CHECK = TRUE
  352.     SECONDS.PER.SESSION! = 4
  353.     CALL BUFFILE ("MENU0")
  354.     BYPASS.TIME.CHECK = FALSE
  355.     LOCAL.USER = FALSE
  356.     PAGE.LENGTH = PAGE.LENGTH.HOLD
  357.     IF NOT OK THEN _
  358.        PRINT "MENU0 not on default drive"
  359.     LOCATE 2,18
  360.     PRINT LEFT$(VERSION.ID$,8);
  361.     LOCATE 2,58
  362.     X$ = DATE$
  363.     PRINT LEFT$(X$,6)+RIGHT$(X$,2);
  364.     LOCATE 2,72
  365.     PRINT LEFT$(TIME$,5);
  366.     IF DEBUG THEN _
  367.        LOCATE 16,1 : _
  368.        PRINT "DEBUG Active";
  369.     LOCATE 18,23
  370.     PRINT NODE.ID$;
  371.     LOCATE 18,74
  372.     PRINT MID$(STR$(FRE("A")),2)
  373.     IF COLOR.SUPPORT THEN _
  374.        LOCATE 20,23 : _
  375.        PRINT "YES";
  376.     IF RESTRICT.BAUD THEN _
  377.        LOCATE 20,51 : _
  378.        PRINT "NO ";
  379.     IF EXTENDED.LOGGING THEN _
  380.        LOCATE 20,75 : _
  381.        PRINT "YES";
  382.     IF FMS.DIRECTORY$ <> "" THEN _
  383.        LOCATE 22,75 : _
  384.        PRINT "YES";
  385.     END SUB
  386. ' $SUBTITLE: 'BADCHAR - subroutine to check user names for bad characters'
  387. ' $PAGE
  388. '
  389. '  SUBROUTINE NAME    -- BADCHAR
  390. '
  391. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  392. '                           PASSED.NAME$           USER NAME
  393. '
  394. '  OUTPUT PARAMETERS  --    PASSED.NAME$           USER NAME WILL CONTAIN ""
  395. '                                                  IF BAD CHARACTERS FOUND
  396. '
  397. '  SUBROUTINE PURPOSE -- TO CHECK USER NAMES FOR INVALID CHARACTERS
  398. '
  399.     SUB BADCHAR (PASSED.NAME$) STATIC
  400. '
  401.     J = 1
  402.     XX = LEN(PASSED.NAME$)
  403. 457 IF J > XX THEN _
  404.        EXIT SUB
  405.     X = ASC(MID$(PASSED.NAME$,J,1))
  406.     IF (X < 65 OR X > 90) AND _
  407.        (X <> 32 AND X <> 39 AND X <> 45 AND X <> 46) THEN _
  408.        PASSED.NAME$ = "" : _
  409.        EXIT SUB
  410.     J = J + 1
  411.     GOTO 457
  412.     END SUB
  413. ' $SUBTITLE: 'LINE25 - subroutine to build/display RBBS-PCs line 25'
  414. ' $PAGE
  415. '
  416. '  SUBROUTINE NAME    -- LINE25
  417. '
  418. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  419. '                        SUBROUTINE.PARAMETER = 1  BUILD DISPLAY FOR LINE 25
  420. '                        SUBROUTINE.PARAMETER = 2  UPDATE LINE 25
  421. '                        LOCK.STATUS$              STATUS OF LOCKS IN A MULTI-
  422. '                                                  USER ENVIRONMENT OR TIME OF
  423. '                                                  DAY USER LOGGED ON OR THE
  424. '                                                  RE-CYCLED
  425. '
  426. '  OUTPUT PARAMETERS  -- CURSOR.LINE               CURRENT LINE ON SCREEN
  427. '                        CURSOR.ROW                CURRENT ROW ON CURSOR.LINE
  428. '
  429. '  SUBROUTINE PURPOSE -- TO BUILD OR UPDATE RBBS-PC'S LINE 25 DISPLAYED
  430. '                        ON THE PC SCREEN THAT IS RUNNING RBBS-PC.
  431. '
  432.       SUB LINE25 STATIC
  433.       ON SUBROUTINE.PARAMETER GOTO 949,950
  434. '
  435. ' *****************************************************************************
  436. ' *  BUILD LINE 25 DISPLAY                                                    *
  437. ' *****************************************************************************
  438. '
  439. 949 LINE.25$ = MID$("    AVL ",1-4*SYSOP.AVAILABLE,4) + _
  440.                MID$("    ANY ",1-4*SYSOP.ANNOY,4) + _
  441.                MID$("    LPT ",1-4*PRINTER,4) + _
  442.                MID$("SYS",1,-3*SYSOP.NEXT)
  443. '
  444. ' *****************************************************************************
  445. ' *  LINE 25 UPDATE ROUTINE                                                   *
  446. ' *****************************************************************************
  447. '
  448. 950 IF NOT SNOOP THEN _
  449.        EXIT SUB
  450.     CURSOR.LINE = CSRLIN
  451.     CURSOR.ROW = POS(0)
  452.     HH = LEN(ACTIVE.USER.NAME$) + LEN(CI$) + LEN(LINE.25$) + 18
  453.     IF AUTODOWNLOAD.AVAILABLE THEN _
  454.        HH = HH + 4
  455.     LOCATE 25,1
  456.     IF NETWORK.TYPE = 0 THEN _
  457.        IF AUTODOWNLOAD.AVAILABLE THEN _
  458.           LOCK.STATUS$ = SPACE$(3) + _
  459.                          "AD  " + _
  460.                          TIME.LOGGED.ON$ _
  461.        ELSE LOCK.STATUS$ = SPACE$(3)+TIME.LOGGED.ON$
  462.     IF HH>79 THEN _
  463.        HH=78
  464.     PRINT LINE.25$+SPACE$(79-HH)+STR$(USER.SECURITY.LEVEL)+" "+ACTIVE.USER.NAME$+" "+CI$+" "+LOCK.STATUS$;
  465.     LOCATE CURSOR.LINE,CURSOR.ROW
  466.     END SUB
  467. ' $SUBTITLE: 'SRCHCMND    - subroutine to search command list'
  468. ' $PAGE
  469. '
  470. '  SUBROUTINE NAME    -- SRCHCMND
  471. '
  472. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  473. '                        STRT.POS      POSITION TO BEGIN SEARCH AT
  474. '                        ALL.OPTS$     STRING TO SEARCH (COMMAND LIST)
  475. '                        Z$            WHAT TO LOOK FOR
  476. '
  477. '  OUTPUT PARAMETERS  -- WHERE.FOUND   POSITION OF Z$ IN ALL.OPTS$
  478. '                                      0 IF NOT FOUND
  479. '
  480. '  SUBROUTINE PURPOSE -- SEARCHES VALID COMMAND LIST FOR THE REQUESTED
  481. '                        COMMAND.  IF THE SYSOP HAS CONFIGURED RBBS-PC TO
  482. '                        RESTRICT COMMANDS TO ONLY THOSE VALID WITHIN THE
  483. '                        RBBS-PC SUBSYSTEM, THEN ONLY THOSE COMMANDS AND
  484. '                        "GLOBAL" COMMANDS ARE VALID.  OTHERWISE ALL COMMANDS
  485. '                        ARE VALID FROM ANY OF THE RBBS-PC SUBSYSTEMS.
  486. '
  487.      SUB SRCHCMND (STRT.POS,WHERE.FOUND) STATIC
  488. 1240 WHERE.FOUND = INSTR(STRT.POS,ALL.OPTS$,Z$)
  489.      IF WHERE.FOUND = 0 THEN _  'Not found: decide whether to hunt further
  490.         IF STRT.POS < 2 OR RESTRICT.VALID.CMDS THEN _
  491.            EXIT SUB _  ' fully searched or restricted
  492.         ELSE _
  493.            WHERE.FOUND = INSTR(1,ALL.OPTS$,Z$) : _ 'hunt further
  494.            EXIT SUB
  495.      IF NOT RESTRICT.VALID.CMDS THEN _
  496.         EXIT SUB             ' everything found valid
  497. '
  498. ' *****************************************************************************
  499. ' * RESTRICT COMMANDS TO SUBSYSTEMS (EXCEPT GLOBAL AND SYSOP)                 *
  500. ' *****************************************************************************
  501. '
  502.      IF WHERE.FOUND > LEN(ALL.OPTS$)-11 THEN _
  503.         EXIT SUB                          ' ACCEPT GLOBAL & SYSOP
  504.      IF MID$(ALL.OPTS$,WHERE.FOUND,1) = "G" THEN _
  505.         EXIT SUB                          ' ACCEPT GOODBYE/GRAPHICS
  506.      IF (STRT.POS < BEG.FILE AND WHERE.FOUND >= BEG.FILE ) OR _
  507.         (STRT.POS < BEG.UTIL AND WHERE.FOUND >= BEG.UTIL ) THEN _
  508.           WHERE.FOUND = 0                 ' REJECT: NOT IN SECTION
  509.      END SUB
  510. ' $SUBTITLE: 'HELP    - Processes requests for help'
  511. ' $PAGE
  512. '
  513. '  SUBROUTINE NAME    -- HELP
  514. '
  515. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  516. '                       SECTION             ORDER OF 1ST COMMAND IN CURRENT
  517. '                                              SECTION
  518. '                       GRAPHICS.DEFAULT    WHAT GRAPHICS TYPE USER WANTS
  519. '                       HELP.DEFAULT$       HELP GET IF PRESS ENTER
  520. '                       HELP.PATH$
  521. '                       HELP.EXTENSION$
  522. '                       BEG.FILE
  523. '                       BEG.MAIN
  524. '                       BEG.UTIL
  525. '
  526. '  OUTPUT PARAMETERS  -- DISPLAYS HELP
  527. '
  528. '  SUBROUTINE PURPOSE -- THE MAIN HELP PROCESSOR FOR RBBS.  PUTS UP THE
  529. '                        OPTIONAL MENU.  ACCEPTS HELP WITH INDIVIDUAL
  530.      SUB HELP (SECTION,GRAPHIC.DEFAULT$,HELP.DEFAULT$) STATIC
  531. 1330 HELP.MENU$ = HELP.PATH$+"HELP"+HELP.EXTENSION$
  532.      GOT.MENU = TRUE
  533.      IF Q>1 THEN _
  534.         ANS.INDEX = 2 : _
  535.         LAST.INDEX = Q: _
  536.         GOTO 1332
  537. 1331 IF GOT.MENU THEN _
  538.         FILE.NAME$ = HELP.MENU$ : _
  539.         GOSUB 1350 : _
  540.         GOT.MENU = OK
  541.      ANS.INDEX = 1
  542.      A$ = "HELP with (LETTER/SECTION/TOPIC, [ENTER]="+HELP.DEFAULT$+", [QH]=quit HELP)"
  543.      SUBROUTINE.PARAMETER = 1
  544.      CALL TGET
  545.      IF SUBROUTINE.PARAMETER = -1 THEN _
  546.         EXIT SUB
  547.      IF Q = 0 THEN _
  548.         Q = 1:_
  549.         B$(1) = HELP.DEFAULT$
  550.      LAST.INDEX = Q
  551. 1332 Z$ = B$(ANS.INDEX)
  552.      CALL ALLCAPS (Z$)
  553.      IF Z$="QH" THEN _
  554.         EXIT SUB
  555.      IF Z$ = "?" THEN _
  556.         Z$ = "H"
  557.      CALL BADFILE (Z$,BAD.FILE.NAME.INDEX)
  558.      ON BAD.FILE.NAME.INDEX GOTO 1333,1340,1340
  559. 1333 IF LEN(Z$) = 1 THEN _
  560.         CALL SRCHCMND (SECTION,FF) : _
  561.         IF FF<1 THEN _
  562.            OK = FALSE :_
  563.            GOTO 1334 _
  564.         ELSE X = -(FF>=BEG.MAIN)-(FF>=BEG.FILE)-(FF>=BEG.UTIL):_
  565.              Z$ = MID$("MFU",X,1) + Z$
  566.      FILE.NAME$ = HELP.PATH$ + Z$ + HELP.EXTENSION$
  567.      GOSUB 1350
  568. 1334 IF NOT OK THEN _
  569.         A$ = "No help for "+Z$ :_
  570.         CALL QTPUT (A$,1) : _
  571.         CALL UPDTCALR (A$,2)
  572.      ANS.INDEX = ANS.INDEX + 1
  573.      IF ANS.INDEX <= LAST.INDEX THEN _
  574.         GOTO 1332
  575.      GOTO 1331
  576. 1340 OK = FALSE
  577.      GOTO 1334
  578. 1350 CALL GRAPHIC (GRAPHIC.DEFAULT$)
  579.      CALL BUFFILE (FILE.NAME$)
  580.      RETURN
  581.      END SUB
  582. ' $SUBTITLE: 'QTPUT    - subroutine to quickly write to terminal'
  583. ' $PAGE
  584. '
  585. '  SUBROUTINE NAME    -- QTPUT
  586. '
  587. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  588. '                        STRNG$        STRING TO WRITE OUT
  589. '                        NUM.RETURNS   NUMBER OF CARRIAGE RETURNS
  590. '
  591. '  OUTPUT PARAMETERS  -- NONE
  592. '
  593. '  SUBROUTINE PURPOSE -- SUBROUTINE TO QUICKLY WRITE TO THE TERMINAL.  THIS IS
  594. '                        IS DIFFERENT FROM "TPUT" IN THE THINGS IT DOESN'T DO:
  595. '                                A.) NO FUNCTION KEY CHECK,
  596. '                                B.) NO CONVERSION TO UPPER CASE,
  597. '                                C.) NO STRING RE-INITILIZATION OF "STRNG$",
  598. '                                D.) NO CHECK FOR CARRIER PRESENT, AND
  599. '                                E.) NO CHECK FOR IMBEDDED CARRIAGE RETURN IN
  600. '                                       "STRNG$".
  601. '                                F.) NO SUPPORT FOR XON/XOFF
  602. '
  603.       SUB QTPUT (STRNG$,NUM.RETURNS) STATIC
  604.       IF UPPER.CASE THEN _
  605.          GOTO 1476
  606.       IF COLOR.SUPPORT THEN _
  607.          IF SNOOP THEN _
  608.             GOTO 1476
  609.       IF NOT LOCAL.USER THEN _
  610.          PRINT #3,STRNG$;
  611.       IF SNOOP THEN _
  612.          PRINT STRNG$;
  613.       CALL SKIPLINE (NUM.RETURNS)
  614.       GOTO 1477
  615. 1476  A$ = STRNG$
  616.       SUBROUTINE.PARAMETER = 4
  617.       CALL TPUT
  618.       CALL SKIPLINE (NUM.RETURNS)
  619. 1477  END SUB
  620. ' $SUBTITLE: 'PRTCRLF  - subroutine to write snoop lines'
  621. ' $PAGE
  622. '
  623. '  SUBROUTINE NAME    -- PRTCRLF
  624. '
  625. '  INPUT PARAMETERS   -- PARAMETER          MEANING
  626. '                         STRNG$             STRING TO WRITE TO SCREEN
  627. '
  628. '  OUTPUT PARAMETERS  -- NONE
  629. '
  630. '  SUBROUTINE PURPOSE -- TO WRITE OUT LINES TO THE LOCAL SYSOP'S SCREEN THAT
  631. '                        MAY HAVE INTERNAL CARRIAGE RETURN AND LINE FEEDS
  632. '                        IMBEDDED IN IT.
  633. '
  634.      SUB PRTCRLF (STRNG$) STATIC
  635. 1478 CURSOR.ROW = 1
  636.      L = LEN(STRNG$)
  637.      NUM.RETURNS = 0
  638.      WHILE CURSOR.ROW <= L
  639.        CURSOR.LINE = CURSOR.ROW + _
  640.                      INSTR(MID$(STRNG$,CURSOR.ROW) + _
  641.                      CARRIAGE.RETURN$,CARRIAGE.RETURN$) - 2
  642.        S1 = -(CURSOR.LINE < L)
  643.        PRINT MID$(STRNG$,CURSOR.ROW,CURSOR.LINE-CURSOR.ROW + 1); _
  644.              MID$(LINE.FEED$,1,S1);
  645.        CURSOR.ROW = CURSOR.LINE + LEN(RETURN.LINE.FEED$) + 1
  646.        NUM.RETURNS = NUM.RETURNS + S1
  647.      WEND
  648.      END SUB
  649. ' $SUBTITLE: 'SKIPLINE - subroutine to write a blank line to user'
  650. ' $PAGE
  651. '
  652. '  SUBROUTINE NAME    -- SKIPLINE
  653. '
  654. '  INPUT PARAMETERS   --   PARAMETER             MEANING
  655. '                        LOCAL.USER
  656. '                        MODEM.STATUS.REGISTER
  657. '                        NUM.RETURNS
  658. '                        RETURN.LINE.FEED$
  659. '                        SNOOP
  660. '
  661. '  OUTPUT PARAMETERS  -- NONE
  662. '
  663. '  SUBROUTINE PURPOSE -- SKIP A LINE ON THE USER'S TERMINAL
  664. '
  665.       SUB SKIPLINE (NUM.RETURNS) STATIC
  666. 1485  IF NOT LOCAL.USER AND INP(MODEM.STATUS.REGISTER) > 127 THEN _
  667.          FOR I=1 TO NUM.RETURNS:PRINT #3,RETURN.LINE.FEED$;:NEXT
  668.       IF SNOOP THEN _
  669.          FOR I=1 TO NUM.RETURNS:PRINT:NEXT
  670.       LINES.PRINTED = LINES.PRINTED + NUM.RETURNS
  671.       END SUB
  672. ' $SUBTITLE: 'SETCRLF -- subroutine to set up nulls/lf's for output'
  673. ' $PAGE
  674. '
  675. '  SUBROUTINE NAME    -- SETCRLF
  676. '
  677. '  INPUT PARAMETERS   --   PARAMETER          MEANING
  678. '                        CARRIAGE.RETURN$    CARRIAGE RETURN CHARACTER
  679. '                        CI$                 CITY/STATE OF CALLER
  680. '                        LINE.FEED$          LINE FEED CHARACTER
  681. '                        LINE.FEEDS          LINE FEED SWITCH
  682. '                        NUL$                NULL CHARACTER
  683. '
  684. '  OUTPUT PARAMETERS  -- RETURN.LINE.FEED$   END-OF-LINE STRING
  685. '
  686. '  SUBROUTINE PURPOSE -- SET UP THE NECESSARCY NULLS/LINE FEEDS TO END
  687. '                        EACH OUTPUT TO THE COMMUNICATIONS PORT WITH
  688. '
  689.       SUB SETCRLF STATIC
  690. 1496  RETURN.LINE.FEED$ = MID$(CARRIAGE.RETURN$,1,-(NOT LOCAL.USER)) + _
  691.                           NUL$ + _
  692.                           MID$(LINE.FEED$,1,-(LINE.FEEDS <> 0))
  693.       END SUB
  694. ' $SUBTITLE: 'SETBAUD - subroutine to set the baud rate in the RS232'
  695. ' $PAGE
  696. '
  697. '  SUBROUTINE NAME    -- SETBAUD
  698. '
  699. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  700. '                         BAUD.RATE.DIVISOR   NUMBER TO DIVIDE THE 8250 CHIP'S
  701. '                                             PROGRAMABLE CLOCK TO ADJUST THE
  702. '                                             BAUD RATE TO THE USER'S BAUD
  703. '                                             RATE (INDEPENDENT OF THE BAUD
  704. '                                             RATE USED TO OPEN THE COMM. PORT)
  705. '
  706. '        DESIRED BAUD        DIVISIOR (DECIMAL) TO OBTAIN DESIRED BAUD RATE
  707. '            RATE              PCjr         PC AND XT
  708. '              50             2237             2304
  709. '              75             1491             1536
  710. '             110             1017             1047
  711. '             134.5            832              857
  712. '             150              746              768
  713. '             300              373              384
  714. '             600              186              192
  715. '            1200               93               96
  716. '            1800               62               64
  717. '            2000               56               58
  718. '            2400               47               48
  719. '            3600               31               32
  720. '            4800               23               24
  721. '            7200          not available         16
  722. '            9600          not available         12
  723. '
  724. '  OUTPUT PARAMETERS  -- BAUD RATE SET IN THE RS232 INTERFACE
  725. '
  726. '  SUBROUTINE PURPOSE -- TO SET THE BAUD RATE IN THE RS232 INTERFACE
  727. '                        INDEPENDENT OF THE BAUD RATE THE COMMUNICATIONS PORT
  728. '                        WAS OPENED AT
  729. '
  730.       SUB SETBAUD STATIC
  731. '
  732. ' *****************************************************************************
  733. ' *  BAUD RATE CHANGE ROUTINE                                                 *
  734. ' *****************************************************************************
  735. '
  736. 1654 LINE.CONTROL.STATUS = INP(LINE.CONTROL.REGISTER)
  737.      MSB.SAVE = INP(MSB)
  738.      OUT MSB,0
  739.      OUT LINE.CONTROL.REGISTER,LINE.CONTROL.STATUS OR 128
  740.      MOST.SIGNIFICANT.BYTE = FIX (BAUD.RATE.DIVISOR / 256)
  741.      LEAST.SIGNIFICANT.BYTE = BAUD.RATE.DIVISOR - (MOST.SIGNIFICANT.BYTE * 256)
  742.      OUT LSB,LEAST.SIGNIFICANT.BYTE
  743.      OUT MSB,MOST.SIGNIFICANT.BYTE
  744.      OUT LINE.CONTROL.REGISTER,LINE.CONTROL.STATUS
  745.      OUT MSB,MSB.SAVE
  746.      END SUB
  747. ' $SUBTITLE: 'KILLMSG - subroutine to delete messages'
  748. ' $PAGE
  749. '
  750. '  SUBROUTINE NAME    -- KILLMSG
  751. '
  752. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  753. '                         MESSAGE.TO.KILL              MESSAGE NUMBER TO KILL
  754. '                         ACTIVE.MESSAGES              NUMBER ACTIVE MESSAGES
  755. '
  756. '  OUTPUT PARAMETERS  --  NONE
  757. '
  758. '  SUBROUTINE PURPOSE --  TO KILL/DELETE OLD OR UNNECESSARY MESSAGES
  759. '
  760.      SUB KILLMSG (MESSAGE.TO.KILL,ACTIVE.MESSAGES) STATIC
  761. '
  762.      FIELD #1,128 AS MESSAGE.RECORD$
  763.      QX = 1
  764. 3955 IF QX > ACTIVE.MESSAGES THEN _
  765.         A$ = "No such msg #" + STR$(MESSAGE.TO.KILL) : _
  766.         GOTO 4031
  767.      IF M(QX,2) = MESSAGE.TO.KILL AND MESSAGE.TO.KILL >= 1 THEN _
  768.         GOTO 3970
  769.      QX = QX + 1
  770.      GOTO 3955
  771. 3970 SUBROUTINE.PARAMETER = 3
  772.      CALL FILELOCK
  773.      GET 1,M(QX,1)
  774.      IF SYSOP THEN _
  775.         GOTO 4030
  776. 3980 Z$ = MID$(MESSAGE.RECORD$,101,15)
  777.      Z$ = LEFT$(Z$ + SPACE$(2),INSTR(Z$ +SPACE$(2),SPACE$(2))-1)
  778.      IF LEN(Z$) = 0 THEN _
  779.         GOTO 4030
  780. 3990 IF Z$ = "^READ^" OR Z$ = "^KILL^" THEN _
  781.         IF INSTR(MESSAGE.RECORD$,ACTIVE.USER.NAME$) THEN _
  782.            GOTO 4030 _
  783.         ELSE MESSAGE.PASSWORD = TRUE : _
  784.              ATTEMPTS.ALLOWED = 0 : _
  785.              CALL QTPUT("Only sender & receiver can kill",1): _
  786.              GOTO 4031
  787. 4000 IF LEFT$(Z$,1) = "!" THEN _
  788.         Z$ = MID$(Z$,2)
  789. 4010 PASSWORD.SAVE$ = Z$ + SPACE$(15-LEN(Z$))
  790.      ATTEMPTS.ALLOWED = 1
  791.      MESSAGE.PASSWORD = TRUE
  792.      CALL PASSWORD
  793.      IF PASSWORD.FAILED THEN _
  794.         GOTO 4031
  795. 4030 LSET MESSAGE.RECORD$ = LEFT$(MESSAGE.RECORD$,115) + _
  796.                             DELETED.MESSAGE$ + _
  797.                             MID$(MESSAGE.RECORD$,117)
  798.      PUT 1,LOC(1)
  799.      A$ = "Killed Msg # " + STR$(MESSAGE.TO.KILL)
  800.      SUBROUTINE.PARAMETER = 4
  801.      CALL FILELOCK
  802.      SUBROUTINE.PARAMETER = 5
  803.      CALL TPUT
  804.      EXIT SUB
  805. 4031 SUBROUTINE.PARAMETER = 4
  806.      CALL TPUT
  807.     END SUB
  808. ' $SUBTITLE: 'GETIME - subroutine to calculate elapsed time'
  809. ' $PAGE
  810. '
  811. '  SUBROUTINE NAME    -- GETIME
  812. '
  813. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  814. '                         TIME.LOGGED.ON$
  815. '
  816. '  OUTPUT PARAMETERS  --  HH                     NUMBER OF HOURS ON
  817. '                         MM                     NUMBER OF MINUTES ON
  818. '                         SS                     NUMBER OF SECONDS ON
  819. '
  820. '  SUBROUTINE PURPOSE --  CALCULATE THE ELASPED TIME A USER HAS BEEN ON
  821. '
  822.      SUB GETIME STATIC
  823. 9140 H = VAL(MID$(TIME.LOGGED.ON$,1,2))
  824.      M = VAL(MID$(TIME.LOGGED.ON$,4,2))
  825.      S = VAL(MID$(TIME.LOGGED.ON$,7,2))
  826.      X$ = TIME$
  827.      HH = VAL(MID$(X$,1,2))
  828.      MM = VAL(MID$(X$,4,2))
  829.      JJ = VAL(MID$(X$,7,2))
  830.      IF S <= JJ THEN _
  831.         SSS = JJ-S _
  832.      ELSE SSS = 60-(S-JJ) : _
  833.           M = M + 1
  834. 9150 IF M <= MM THEN _
  835.         MMM = MM-M _
  836.      ELSE MMM = 60-(M-MM) : _
  837.           H = H + 1
  838. 9160 IF H <= HH THEN _
  839.         HHH = HH-H : _
  840.         GOTO 9161 _
  841.      ELSE HHH = 24-(H-HH)
  842. 9161 END SUB
  843. ' $SUBTITLE: 'DEFAULTU - subroutine to update user defauts'
  844. ' $PAGE
  845. '
  846. '  SUBROUTINE NAME    -- DEFAULTU
  847. '
  848. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  849. '                         AUTODOWNLOAD.AVAILABLE
  850. '                         CHECK.BULLETIN.LOGON
  851. '                         EXPERT.USER
  852. '                         GR
  853. '                         LAST.MESSAGE.READ
  854. '                         LINE.FEEDS
  855. '                         NULLS
  856. '                         PAGE.LENGTH
  857. '                         PROMPT.BELL
  858. '                         REG.DATE$
  859. '                         REQ.QUES.ANSWERED
  860. '                         RIGHT.MARGIN
  861. '                         SKIP.FILES.LOGON
  862. '                         TIMES.LOGGED.ON
  863. '                         UPPER.CASE
  864. '                         USER.OPTIONS$
  865. '                         USER.TRANSFER.DEFAULT$
  866. '
  867. '  OUTPUT PARAMETERS  --  USER.OPTONS$
  868. '
  869. '  SUBROUTINE PURPOSE --  TO UPDATE THE USER'S RECORD WITH THEIR OPTIONS
  870. '
  871.      SUB DEFAULTU STATIC
  872. '
  873. ' *****************************************************************************
  874. ' * UPDATE USER DEFAULTS                                                      *
  875. ' *****************************************************************************
  876. '
  877. 9600 LSET USER.OPTIONS$ = _
  878.         MKI$(TIMES.LOGGED.ON) + _
  879.         MKI$(LAST.MESSAGE.READ) + _
  880.         USER.TRANSFER.DEFAULT$ + _
  881.         MID$(STR$(GR),2,1) + _
  882.         MKI$(RIGHT.MARGIN) + _
  883.         MKI$(-PROMPT.BELL-2*EXPERT.USER-4*NULLS-8*UPPER.CASE-16*LINE.FEEDS_
  884.              -32*CHECK.BULLETIN.LOGON - 64*SKIP.FILES.LOGON_
  885.              -128*AUTODOWNLOAD.AVAILABLE - 256*REQ.QUES.ANSWERED) + _
  886.         REG.DATE$ + _
  887.         CHR$(PAGE.LENGTH) + _
  888.         STRING$(1,0)
  889.      END SUB
  890. ' $SUBTITLE: 'RECOVMSG - subroutine to recover deleted messages'
  891. ' $PAGE
  892. '
  893. '  SUBROUTINE NAME    -- RECOVMSG
  894. '
  895. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  896. '                         MESSAGE.TO.RECOVER          MESSAGE NUMBER TO RECOVER
  897. '                         FIRST.MESSAGE.RECORD        RECORD # FOR FIRST MSG
  898. '
  899. '  OUTPUT PARAMETERS  --  ACTION.FLAG                 SET TO 0 IF ERROR
  900. '                                                     SET TO -1 IF NO ERROR
  901. '
  902. '  SUBROUTINE PURPOSE --  TO RECOVER DELETED MESSAGES.  NOTE THAT THIS IS ONLY
  903. '                         POSSIBLE IF YOU HAVE NOT COMPRESSED YOUR MESSAGE FILE
  904. '                         USING CONFIG.
  905.      SUB RECOVMSG (MESSAGE.TO.RECOVER,FIRST.MESSAGE.RECORD,ACTION.FLAG) STATIC
  906.       FIELD #1,128 AS MESSAGE.RECORD$
  907. 10410 MESSAGE.RECORD = FIRST.MESSAGE.RECORD
  908.       SUBROUTINE.PARAMETER = 5
  909.       CALL TPUT
  910. 10420 GET 1,MESSAGE.RECORD
  911.       NUMBER.RECORDS.IN.MESSAGE = VAL(MID$(MESSAGE.RECORD$,117,4))
  912.       IF NUMBER.RECORDS.IN.MESSAGE < 1 THEN _
  913.          A$ = "USE CONFIG TO REPAIR YOUR MESSAGE FILE" : _
  914.          SUBROUTINE.PARAMETER = 5 : _
  915.          GOTO 10485
  916.       IF MESSAGE.RECORD >= NEXT.MESSAGE.RECORD THEN _
  917.          A$ = "No Msg #" + STR$(MESSAGE.TO.RECOVER) : _
  918.          GOTO 10485
  919. 10440 IF VAL(MID$(MESSAGE.RECORD$,2,4)) <> MESSAGE.TO.RECOVER THEN _
  920.          MESSAGE.RECORD = MESSAGE.RECORD + NUMBER.RECORDS.IN.MESSAGE : _
  921.          GOTO 10420
  922. 10450 IF INSTR(MESSAGE.RECORD$,DELETED.MESSAGE$) <> 0 THEN _
  923.          SUBROUTINE.PARAMETER = 3 : _
  924.          CALL TPUT : _
  925.          LSET MESSAGE.RECORD$ = LEFT$(MESSAGE.RECORD$,115) + _
  926.                                 ACTIVE.MESSAGE$ + _
  927.                                 MID$(MESSAGE.RECORD$,117) : _
  928.          PUT 1,LOC(1) : _
  929.          SUBROUTINE.PARAMETER = 4 : _
  930.          CALL TPUT : _
  931.          A$ = "Restored Msg #" + STR$(MESSAGE.TO.RECOVER) : _
  932.          ACTION.FLAG = TRUE : _
  933.          GOTO 10485
  934. 10480 A$ = "Msg #" + STR$(MESSAGE.TO.RECOVER) + " not Dead"
  935. 10485 SUBROUTINE.PARAMETER = 5
  936.       CALL TPUT
  937.       END SUB
  938. ' $SUBTITLE: 'UPDATEU -- Update the users record at logoff'
  939. ' $PAGE
  940. '  SUBROUTINE NAME    -- UPDATEU
  941. '
  942. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  943. '                        ADJUSTED.SECURITY
  944. '                        CURRENT.DATE$
  945. '                        DOWNLOADS
  946. '                        ELAPSED.TIME
  947. '                        LIST.DIRECTORY
  948. '                        MAIN.USER.FILE.INDEX
  949. '                        SECONDS.PER.SESSION!
  950. '                        UPLOADS
  951. '                        USER.SECURITY.LEVEL
  952. '
  953. '  OUTPUT PARAMETERS  -- ELAPSED.TIME$
  954. '                        LIST.NEW.DATE$
  955. '                        SECURITY.LEVEL$
  956. '                        USER.DOWNLOADS$
  957. '                        USER.UPLOADS$
  958. '
  959. '  SUBROUTINE PURPOSE -- UPDATE THE USER RECORD FOR THE USER WHEN THE USER
  960. '                        EXITS RBBS-PC.
  961. '
  962.       SUB UPDATEU STATIC
  963. 10600 USER.FILE.INDEX = MAIN.USER.FILE.INDEX
  964.       SUBROUTINE.PARAMETER = 6
  965.       CALL FILELOCK
  966.       CALL OPENUSER
  967.       FIELD 5,31 AS USER.NAME$, _
  968.               15 AS PASSWORD$, _
  969.                2 AS SECURITY.LEVEL$, _
  970.               14 AS USER.OPTIONS$,  _
  971.               24 AS CITY.STATE$, _
  972.               19 AS MACHINE.TYPE$, _
  973.               14 AS LAST.DATE.TIME.ON$, _
  974.                3 AS LIST.NEW.DATE$, _
  975.                2 AS USER.DOWNLOADS$, _
  976.                2 AS USER.UPLOADS$, _
  977.                2 AS ELAPSED.TIME$
  978. 10604 GET 5,USER.FILE.INDEX
  979.       CALL DEFAULTU
  980.       IF LIST.DIRECTORY THEN _
  981.          LSET LIST.NEW.DATE$ = CHR$(VAL(MID$(CURRENT.DATE$,7,2)))+_
  982.                                CHR$(VAL(MID$(CURRENT.DATE$,1,2)))+_
  983.                                CHR$(VAL(MID$(CURRENT.DATE$,4,2)))
  984. 10605 LSET USER.DOWNLOADS$ = MKI$(DOWNLOADS)
  985.       LSET USER.UPLOADS$ = MKI$(UPLOADS)
  986.       CALL TIMEREMAIN (TIME.REMAINING!)
  987.       LSET ELAPSED.TIME$ = MKI$(ELAPSED.TIME + _
  988.                          (SECONDS.PER.SESSION! / 60) - _
  989.                           TIME.REMAINING!)
  990.       IF ADJUSTED.SECURITY THEN _
  991.          LSET SECURITY.LEVEL$ = MKI$(USER.SECURITY.LEVEL)
  992.       PUT 5,USER.FILE.INDEX
  993.       END SUB
  994. ' $SUBTITLE: 'DOSEXIT -- Setup to exit to DOS for SYSOP'
  995. ' $PAGE
  996. '  SUBROUTINE NAME    -- DOSEXIT
  997. '
  998. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  999. '                        COM.PORT$
  1000. '                        DOORS.TERMINAL.TYPE
  1001. '                        MULTI.LINK.PRESENT
  1002. '                        RBBS.BAT$
  1003. '                        REDIRECT.IO.METHOD
  1004. '
  1005. '  OUTPUT PARAMETERS  -- Q                    NUMBER OF LINES TO WRITE OUT TO
  1006. '                                             RCTTY.BAT$
  1007. '                        B$()                 LINES TO WRITE OUT TO RCTTY.BAT$
  1008. '
  1009. '  SUBROUTINE PURPOSE -- SET UP B$() AND Q IN ORDER TO CALL "RBBSEXIT" AND
  1010. '                        EXIT TO DOS FOR THE REMOTE RBBS-PC SYSOP
  1011. '
  1012.       SUB DOSEXIT STATIC
  1013. 10934 IF MULTI.LINK.PRESENT AND _
  1014.          DOORS.TERMINAL.TYPE > 0 THEN _
  1015.          FF = 0 : _
  1016.          GOTO 10950
  1017.       A$(1) = "ECHO OFF"
  1018.       IF REDIRECT.IO.METHOD THEN _
  1019.          FF = 5 : _
  1020.          A$(2) = "CTTY " + COM.PORT$ : _
  1021.          A$(3) = DISK.FOR.DOS$ + "COMMAND" : _
  1022.          A$(4) = "CTTY CON" : _
  1023.          A$(5) = RBBS.BAT$ _
  1024.       ELSE _
  1025.          FF = 3 : _
  1026.          A$(2) = DISK.FOR.DOS$ + "COMMAND >" + COM.PORT$ + " <" + COM.PORT$ : _
  1027.          A$(3) = RBBS.BAT$
  1028. 10950 SUBROUTINE.PARAMETER = 1
  1029.       CALL AMORPM
  1030.       CALL UPDTCALR ("Exited to DOS at " + TIM$,2)
  1031.       CALL QTPUT("RBBS-PC " + VERSION.ID$,1)
  1032.       CALL QTPUT("SYSOP in Remote Console Mode",1)
  1033.       CALL RBBSEXIT (A$(),FF)
  1034.       END SUB
  1035. ' $SUBTITLE: 'WORDINFILE -- Searches a file to find a word'
  1036. ' $PAGE
  1037. '  SUBROUTINE NAME    -- WORDINFILE
  1038. '
  1039. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  1040. '                        FILNAME$      FILE TO SEARCH IN
  1041. '                        STRNG$        STRING TO SEARCH FOR
  1042. '
  1043. '  OUTPUT PARAMETERS  -- INFILE        WHETHER STRING FOUND IN FILE
  1044. '
  1045. '  SUBROUTINE PURPOSE -- SEARCHES FOR "STRNG$" IN FILE "FILNAME$."  USED TO
  1046. '                        LIMIT DOORS AND QUESTIONNAIRES TO THOSE SPECIFIED
  1047. '                        IN THEIR MENU FILES.  THE "STRNG$" IS CAPITALIZED
  1048. '                        BUT NOT THE LINES IN THE FILE, SO MUST BE EXACT
  1049. '                        CASE-SENSITIVE MATCH TO BE FOUND.  THE ONLY CHARACTER
  1050. '                        THAT CAN IMMEDIATELY PROCEED OR END A NAME TO BE
  1051. '                        FOUND MUST BE A BLANK.
  1052. '
  1053.       SUB WORDINFILE (FILNAME$,STRNG$,INFILE) STATIC
  1054. 10976 INFILE = FALSE
  1055.       CALL FINDIT (FILNAME$)
  1056.       IF NOT OK THEN _
  1057.          EXIT SUB
  1058.       X = 0
  1059.       CALL ALLCAPS (STRNG$)
  1060.       WHILE NOT EOF(2) AND X < 1
  1061.         LINE INPUT #2,A$
  1062.         Y = 1
  1063. 10978   X = INSTR(Y,A$,STRNG$)
  1064.         IF X < 1 THEN _
  1065.            GOTO 10980
  1066.         Y = X+1
  1067.         IF X>1 THEN _
  1068.            IF MID$(A$,X-1,1)<>" " THEN _
  1069.               X=0
  1070.         IF X>0 THEN _
  1071.            L = LEN(STRNG$) : _
  1072.            IF LEN(A$) >= (X+L) THEN _
  1073.               IF MID$(A$,X+L,1)<>" " THEN _
  1074.                  X=0
  1075.         IF X=0 THEN _
  1076.            GOTO 10978
  1077. 10980 WEND
  1078.       CLOSE 2
  1079.       INFILE = (X > 0)
  1080.       END SUB
  1081. ' $SUBTITLE: 'DOOREXIT -- Setup to exit to a "door"'
  1082. ' $PAGE
  1083. '  SUBROUTINE NAME    -- DOOREXIT
  1084. '
  1085. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  1086. '                        MULTI.LINK.PRESENT
  1087. '                        NODE.ID$
  1088. '                        RBBS.BAT$
  1089. '                        Z$
  1090. '
  1091. '  OUTPUT PARAMETERS  -- Q                    NUMBER OF LINES TO WRITE OUT TO
  1092. '                                             RCTTY.BAT$
  1093. '                        B$()                 LINES TO WRITE OUT TO RCTTY.BAT$
  1094. '
  1095. '  SUBROUTINE PURPOSE -- SET UP B$() AND Q IN ORDER TO CALL "EXITRBBS" AND
  1096. '                        EXIT RBBS-PC TO INVOKE ANTOHER PROGRAM
  1097. '
  1098.       SUB DOOREXIT STATIC
  1099. 10987 A$(1) = DISK.FOR.DOS$+ "COMMAND /C " + Z$ + NODE.ID$
  1100.       A$(2) = RBBS.BAT$
  1101.       A$ = Z$ + " door opened at " + TIME$ + " on " + DATE$
  1102.       SUBROUTINE.PARAMETER = 5
  1103.       CALL TPUT
  1104.       CALL UPDTCALR (LEFT$(Z$,LEN(Z$)-4) + " door opened!",2)
  1105.       CALL RBBSEXIT (A$(),2)
  1106.       END SUB
  1107. ' $SUBTITLE: 'RBBSEXIT -- Setup to exit to a RBBS'
  1108. ' $PAGE
  1109. '  SUBROUTINE NAME    -- RBBSEXIT
  1110. '
  1111. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  1112. '                        LINE.ARA        Array of lines to write to batch file
  1113. '                        NUM.LINES       How many lines in array
  1114. '
  1115. '  OUTPUT PARAMETERS  -- RCTTY.BAT$
  1116. '
  1117. '  SUBROUTINE PURPOSE -- TO CREATE A BATCH FILE THAT CONTROL CAN BE PASSED TO
  1118. '                        AND TO EXIT RBBS-PC WHILE STILL KEEPING CARRIER UP
  1119. '
  1120.       SUB RBBSEXIT (LINE.ARA$(1),NUM.LINES) STATIC
  1121. 10992 CLOSE 2
  1122.       IF NUM.LINES = 0 THEN _
  1123.          GOTO 10994
  1124.       OPEN "O",2,RCTTY.BAT$
  1125.       FOR I = 1 TO NUM.LINES
  1126.       IF LINE.ARA$(I) <> "" THEN _
  1127.          PRINT #2,LINE.ARA$(I)
  1128.       NEXT
  1129.       CLOSE 2
  1130. 10994 CLOSE 3
  1131.       EXIT.TO.DOORS = TRUE
  1132.       OUT MODEM.CONTROL.REGISTER,INP(MODEM.CONTROL.REGISTER) OR 1
  1133.       CALL MLINIT (2)
  1134. 10996 IF NOT SYSOP THEN _
  1135.          CALL UPDATEU : _
  1136.          SUBROUTINE.PARAMETER = 8 : _
  1137.          CALL FILELOCK
  1138.       CALL GETIME
  1139.       CALL UPDATEC
  1140.       CALL SAVEPROF (1)
  1141.       IF NUM.LINES = 0 THEN _
  1142.          EXIT SUB
  1143.       SYSTEM
  1144.       END SUB
  1145. ' $SUBTITLE: 'UNTILRIGHT - subroutine to ask question until answer okay'
  1146. ' $PAGE
  1147. '
  1148. '  SUBROUTINE NAME    -- UNTILRIGHT
  1149. '
  1150. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  1151. '                        QUES$         QUESTION TO BE ASKED THE USER
  1152. '                        ANS$          LOCATION TO STORE THE ANSWER
  1153. '                        MIN.LEN       MINIMUM LENGTH OF ANSWER
  1154. '                        MAX.LEN       MAX LENGTH OF ANSWER
  1155. '
  1156. '  OUTPUT PARAMETERS  -- ANS$          RESPONSE TO THE QUESTION WHICH THE
  1157. '                                      CALLERS SAYS IS CORRECT
  1158. '
  1159. '  SUBROUTINE PURPOSE -- SUBROUTINE TO ASK A USER A QUESTION UNTIL THE CALLER
  1160. '                        RESPONDS THAT THE ANSWER IS CORRECT
  1161. '
  1162.       SUB UNTILRIGHT (QUES$,ANS$,MIN.LEN,MAX.LEN) STATIC
  1163. 12880 SUBROUTINE.PARAMETER = 1
  1164.       A$ = QUES$
  1165.       CALL TGET
  1166.       IF SUBROUTINE.PARAMETER = -1 THEN _
  1167.          GOTO 12882
  1168.       IF Q=0 THEN _
  1169.          GOTO 12880
  1170.       IF LEN(B$(1))>MAX.LEN THEN _
  1171.          CALL QTPUT (STR$(MAX.LEN)+" chars max",1) :_
  1172.          GOTO 12880_
  1173.       ELSE IF LEN(B$(1)) < MIN.LEN THEN_
  1174.               CALL QTPUT (STR$(MIN.LEN)+" chars min",1) : _
  1175.               GOTO 12880
  1176.       ANS$ = B$(1)
  1177.       A$ = B$(1) + ", right (Y=[ENTER],N)"
  1178.       CALL TGET
  1179.       IF SUBROUTINE.PARAMETER = -1 THEN _
  1180.          GOTO 12882
  1181.       IF NO THEN _
  1182.          GOTO 12880
  1183.       CALL ALLCAPS (ANS$)
  1184.       EXIT SUB
  1185. 12882 ANS$ = "GUEST"
  1186.       END SUB
  1187. ' $SUBTITLE: 'LOGERROR - subroutine to log errors to CALLERS file'
  1188. ' $PAGE
  1189. '
  1190. '  SUBROUTINE NAME    -- LOGERROR
  1191. '
  1192. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  1193. '                               ERR           ERROR NUMBER DETECTED BY BASIC
  1194. '                               ERL           LAST LINE NUMBER ENCOUNTERED
  1195. '                                             PRIOR TO ENCOUNTERNING ERROR
  1196. '
  1197. '  OUTPUT PARAMETERS  -- NONE
  1198. '
  1199. '  SUBROUTINE PURPOSE -- TO SET UP A STRING TO WRITE TO THE CALLERS LOG
  1200. '                        INDICATING THE DATE, TIME, ERROR, AND ERROR LINE
  1201. '
  1202.       SUB LOGERROR STATIC
  1203. 13660 CALL UPDTCALR("+++ Error " + _
  1204.            STR$(ERR) + _
  1205.            " line " + _
  1206.            STR$(ERL) + _
  1207.            " at " + _
  1208.            TIME$ + _
  1209.            " on " + _
  1210.            DATE$,2)
  1211.       END SUB
  1212. ' $SUBTITLE: 'BADNAME - subroutine to find bad file names'
  1213. ' $PAGE
  1214. '
  1215. '  SUBROUTINE NAME    -- BADNAME
  1216. '
  1217. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  1218. '                        ACTIVE.MESSAGE.FILE$
  1219. '                        ACTIVE.USER.FILE$
  1220. '                        CALLERS.FILE$
  1221. '                        COMMENTS.FILE$
  1222. '                        CONFIG.FILEANAME$
  1223. '                        MAIN.MESSAGE.BACKUP$
  1224. '                        MAIN.MESSAGE.FILE$
  1225. '                        MAXIMUM.VIOLATIONS
  1226. '                        PASSWORDS.FILE$
  1227. '                        RBBS.BAT$
  1228. '                        RCTTY.BAT$
  1229. '                        SUBDIR$()
  1230. '                        SUBDIR.INDEX
  1231. '                        VIOLATION$
  1232. '                        VIOLATIONS.THIS.SESSION
  1233. '                        Z$                          NAME OF FILE
  1234. '
  1235. '  OUTPUT PARAMETERS  -- BAD.FILE.NAME.INDEX         1 = FILE NAME IS OK
  1236. '                                                    2 = SECURITY BREACH TRIED
  1237. '                        VIOLATIONS.THIS.SESSION     NUMBER OF VIOLATIONS
  1238. '                        FILENAME$                   NAME OF FILE
  1239. '
  1240. '  SUBROUTINE PURPOSE -- TO PROTECT RBBS-PC AGAINST THE USE OF BAD FILE NAMES
  1241. '                        TO EITHER CRASH THE SYSTEM OR TO BREACH RBBS-PC'S
  1242. '                        SECURITY
  1243. '
  1244.       SUB BADNAME STATIC
  1245. '
  1246. ' *****************************************************************************
  1247. ' *  TEST FOR SYSTEM FILE ATTEMPT                                             *
  1248. ' *****************************************************************************
  1249. '
  1250. 20235 BAD.FILE.NAME.INDEX = 1
  1251.       Z$ = FILE.NAME$
  1252.       IF INSTR(3,FILE.NAME$,MID$(ACTIVE.MESSAGE.FILE$,3,(LEN(ACTIVE.MESSAGE.FILE$)-2))) THEN _
  1253.          GOTO 20236
  1254.       IF INSTR(3,FILE.NAME$,MID$(ACTIVE.USER.FILE$,3,(LEN(ACTIVE.USER.FILE$)-2))) THEN _
  1255.          GOTO 20236
  1256.       IF INSTR(3,FILE.NAME$,MID$(ACTIVE.USER.FILE$+".BAK",3,(LEN(ACTIVE.USER.FILE$+".BAK")-2))) THEN _
  1257.          GOTO 20236
  1258.       IF INSTR(3,FILE.NAME$,MID$(CALLERS.FILE$,3,(LEN(CALLERS.FILE$)-2))) THEN _
  1259.          GOTO 20236
  1260.       IF INSTR(3,FILE.NAME$,MID$(COMMENTS.FILE$,3,(LEN(COMMENTS.FILE$)-2))) THEN _
  1261.          GOTO 20236
  1262.       IF INSTR(3,FILE.NAME$,MID$(FILESEC.FILE$,3,(LEN(FILESEC.FILE$)-2))) THEN _
  1263.          GOTO 20236
  1264.       IF INSTR(3,FILE.NAME$,MID$(MAIN.MESSAGE.BACKUP$,3,(LEN(MAIN.MESSAGE.BACKUP$)-2))) THEN _
  1265.          GOTO 20236
  1266.       IF INSTR(3,FILE.NAME$,MID$(MAIN.MESSAGE.FILE$,3,(LEN(MAIN.MESSAGE.FILE$)-2))) THEN _
  1267.          GOTO 20236
  1268.       IF INSTR(3,FILE.NAME$,MID$(MAIN.USER.FILE$,3,(LEN(MAIN.USER.FILE$)-2))) THEN _
  1269.          GOTO 20236
  1270.       IF INSTR(3,FILE.NAME$,MID$(MAIN.USER.FILE$+".BAK",3,(LEN(MAIN.USER.FILE$+".BAK")-2))) THEN _
  1271.          GOTO 20236
  1272.       IF INSTR(3,FILE.NAME$,MID$(PASSWORDS.FILE$,3,(LEN(PASSWORDS.FILE$)-2))) THEN _
  1273.          GOTO 20236
  1274.       IF INSTR(3,FILE.NAME$,MID$(RBBS.BAT$,3,(LEN(RBBS.BAT$)-2))) THEN _
  1275.          GOTO 20236
  1276.       IF INSTR(3,FILE.NAME$,MID$(RCTTY.BAT$,3,(LEN(RCTTY.BAT$)-2))) THEN _
  1277.          GOTO 20236
  1278.       CALL BRKFNAME (CONFIG.FILENAME$,DR$,PREFIX$,EXTENSION$,FALSE)
  1279.       IF INSTR(3,FILE.NAME$,MID$(CONFIG.FILENAME$,LEN(DR$)+1)) THEN _
  1280.          GOTO 20236
  1281.       EXIT SUB
  1282. 20236 BAD.FILE.NAME.INDEX = 2
  1283.       END SUB
  1284. ' $SUBTITLE: 'BRKFNAME - subroutine to split file name into components'
  1285. ' $PAGE
  1286. '
  1287. '  SUBROUTINE NAME    -- BRKFNAME
  1288. '
  1289. '  INPUT PARAMETERS   -- PARAMETER                    MEANING
  1290. '                        FILENAME$        FULL NAME OF FILE
  1291. '                        FOR.JOINING      TRUE IF WANT PARTS FORMATTED FOR
  1292. '                                           FORMING FILE NAMES
  1293. '  OUTPUT PARAMETERS  -- DRVPATH$         DRIVE AND PATH
  1294. '                        PREFIX$          PREFIX OF FILE NAME
  1295. '                        EXTENSION$       EXTENSION OF FILE NAME
  1296. '
  1297. ' (E.G. "C:\RBBS\ARCE.COM" HAS "C:\RBBS" AS DRIVE AND PATH,
  1298. '                              "ARCE"    AS PREFIX OF THE FILE NAME, AND
  1299. '                              "COM"     AS THE EXTENSION OF THE FILE NAME.
  1300. '
  1301. ' JOINED FORMAT IS C:\RBBS\,ARCE,.COM
  1302. '
  1303. '  SUBROUTINE PURPOSE -- TO BREAK A FILE NAME INTO ITS COMPONENT PARTS
  1304. '                        OF DRIVE/PATH, PREFIX, AND EXTENSION
  1305. '
  1306. '
  1307.       SUB BRKFNAME (FILENAME$,DRVPATH$,PREFIX$,EXTENSION$,FOR.JOINING) STATIC
  1308. 20282 CALL ALLCAPS (FILENAME$)
  1309.       DRVPATH$ = ""
  1310.       PREFIX$ = ""
  1311.       EXTENSION$ = ""
  1312.       IF LEN(FILENAME$) < 1 THEN _
  1313.          EXIT SUB
  1314.       CALL FINDLAST (FILENAME$,"\",X,Y)
  1315.       IF X < 1 THEN _
  1316.          IF MID$(FILENAME$,2,1) = ":" THEN _
  1317.             DRVPATH$ = LEFT$(FILENAME$,1): _
  1318.             S = 3 _
  1319.          ELSE S = 1 _
  1320.       ELSE DRVPATH$ = LEFT$(FILENAME$,X-1) : _
  1321.            S = X + 1
  1322.       X = INSTR(FILENAME$+".",".")
  1323.       EXTENSION$ = MID$(FILENAME$,X+1,3)
  1324.       PREFIX$ = MID$(FILENAME$,S,X-S)
  1325.       IF NOT FOR.JOINING THEN _
  1326.          EXIT SUB
  1327.       IF LEN(DRVPATH$) = 1 THEN _
  1328.          DRVPATH$ = DRVPATH$ + ":"
  1329.       IF INSTR(DRVPATH$,"\") > 0 THEN _
  1330.          DRVPATH$ = DRVPATH$ + "\"
  1331.       IF LEN(EXTENSION$) > 0 THEN _
  1332.          EXTENSION$ = "." + EXTENSION$
  1333.       END SUB
  1334. ' $SUBTITLE: 'WILDCARD -- Matches string to a pattern'
  1335. ' $PAGE
  1336. '  SUBROUTINE NAME    -- WILDCARD
  1337. '
  1338. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  1339. '                        PATTERN$           PATTERN TO CHECK
  1340. '                        STRNG$             STRING TO FIE
  1341. '
  1342. '  OUTPUT PARAMETERS  -- OK                 TRUE IF MATCH FOUND
  1343. '                                           FALSE IF NO MATCH WAS FOUND
  1344. '
  1345. '  SUBROUTINE PURPOSE  DETERMINE WHETHER A STRING IS AN INSTANCE IN A PATTERN
  1346. '                      SUPPORTED PATTERNS ARE ONLY "?" WHICH REQUIRES A
  1347. '                      CHARACTER BUT CAN BE ANY, AND "*" WHICH MATCHES ANY-
  1348. '                      THING, INCLUDING A NULL STRING.  ANYTHING ELSE IN A
  1349. '                      MUST BE AN EXACT MATCH.
  1350. '
  1351.       SUB WILDCARD (PATTERN$,STRNG$) STATIC
  1352. 20285 OK = TRUE
  1353.       K = 0
  1354.       L = LEN(STRNG$)
  1355. 20286 K = K + 1
  1356.       IF K > L THEN _
  1357.          GOTO 20288
  1358.       B$ = MID$(PATTERN$,K,1)
  1359.       IF B$ = "*" THEN _
  1360.          EXIT SUB
  1361. 20287 IF B$ <> "?" AND MID$(STRNG$,K,1) <> B$ THEN _
  1362.      OK = FALSE : _
  1363.          EXIT SUB
  1364.       GOTO 20286
  1365. 20288 IF L < LEN(PATTERN$) AND MID$(PATTERN$,L + 1,1) <> "*" THEN _
  1366.      OK = FALSE
  1367.       END SUB
  1368. ' $SUBTITLE: 'UPDTUPLOAD -- Updates upload directory'
  1369. ' $PAGE
  1370. '  SUBROUTINE NAME    -- UPDTUPLOAD
  1371. '
  1372. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  1373. '                        FILE.NAME$
  1374. '                        UPLOAD.DIRECTORY$
  1375. '                        FILE.NAME.HOLD$
  1376. '                        SHARE.IT
  1377. '                        FMS.DIRECTORY$
  1378. '                        Q!
  1379. '                        TCA!
  1380. '
  1381. '  OUTPUT PARAMETERS  -- BYTES.IN.FILE#
  1382. '                        SECONDS.PER.SESSION!
  1383. '
  1384. '  SUBROUTINE PURPOSE -- UPON A SUCCESSFUL UPLOAD, ADD ENTRY TO THE UPLOAD
  1385. '                        DIRECTORY AND GIVE ANY SESSION TIME CREDIT.
  1386. '
  1387.       SUB UPDTUPLOAD (CATEGORY.NAME$(1),CATEGORY.CODE$(1)) STATIC
  1388. 20705 CALL FINDIT (FILE.NAME$)
  1389.       IF NOT OK THEN _
  1390.          BYTES.IN.FILE# = 0.0_
  1391.       ELSE_
  1392.          BYTES.IN.FILE# = LOF(2)
  1393.       IF BYTES.IN.FILE# < 1.0 THEN _
  1394.          EXIT SUB                                                    ' C@FORMAT
  1395.       CALL QTPUT("Upload successful",1)
  1396.       X$ = DATE$
  1397.       Z$ = LEFT$(X$,6) + RIGHT$(X$,2)
  1398.       STREW.TO$ = ""
  1399.       Y$ = ""
  1400. 20710 CALL QTPUT("Describe " + FILE.NAME.HOLD$ + _
  1401.            " (/ if for SYSOP only)",1)
  1402.       CALL QTPUT(LEFT$(" |----+---1+0---+---2+0---+---3+0---+---4+0---+-",_
  1403.                  MAX.DESC.LEN+3),1)
  1404.       A$=""
  1405.       SUBROUTINE.PARAMETER = 1
  1406.       CALL TGET
  1407.       CALL CARRIER
  1408.       IF SUBROUTINE.PARAMETER = -1 THEN _
  1409.          B$(1) = "<unavailable>": _
  1410.          GOTO 20712
  1411.       IF LEN(B$(1)) > MAX.DESC.LEN OR LEN(B$(1)) < 3 THEN _
  1412.          GOTO 20710
  1413. 20712 B$ = B$(1)
  1414.       DESC$ = B$
  1415.       IF FMS.DIRECTORY$ <> UPLOAD.DIRECTORY$ THEN _
  1416.          IF LEFT$(B$,1) = "/" THEN _
  1417.             CALL UPDTCALR (B$,2) : _
  1418.             GOTO 20726_
  1419.          ELSE_
  1420.             GOTO 20717
  1421. 20715 IF LEFT$(B$,1) = "/" THEN _
  1422.          B$ = MID$(B$(1),2) : _
  1423.          Y$ = "***" : _
  1424.          GOTO 20722
  1425.       Y$ = DEFAULT.CATEGORY.CODE$
  1426. 20717 IF SUBROUTINE.PARAMETER = -1 OR _
  1427.          USER.SECURITY.LEVEL < SL.CATEGORIZE.UPLOADS THEN _
  1428.          GOTO 20722
  1429. 20719 CALL BUFFILE (UPCAT.HELP$)
  1430. 20720 A$ = "Upload best fits what category (H=help)"
  1431.       SUBROUTINE.PARAMETER = 1
  1432.       CALL TGET
  1433.       IF SUBROUTINE.PARAMETER = -1 THEN _
  1434.          B$ = DEFAULT.CATEGORY.CODE$ : _
  1435.          GOTO 20722
  1436.       IF Q = 0 THEN _
  1437.          GOTO 20719
  1438.       CALL ALLCAPS (B$(1))
  1439.       IF B$(1) = "H" THEN _
  1440.          GOTO 20719
  1441.       CALL CHKNARY (B$(1),CATEGORY.NAME$(),NUM.CATEGORIES,FOUND)
  1442.       IF FOUND>0 THEN _
  1443.          Y$ = CATEGORY.CODE$(FOUND) : _
  1444.          IF LEN(Y$) > 0 AND LEN(Y$) < 4 AND INSTR(Y$,",")=0 THEN _
  1445.             GOTO 20722
  1446.       Y$ = ""
  1447.       IF NOT LIMIT.SEARCH.TO.FMS THEN _
  1448.          STREW.TO$ = DIRECTORY.PATH$ + B$(1) + "." + DIRECTORY.EXTENTION$ : _
  1449.          CALL FINDIT (STREW.TO$) : _
  1450.          IF NOT OK THEN _
  1451.             STREW.TO$ = ""
  1452.       CALL QTPUT ("No such category "+B$(1),1)
  1453.       GOTO 20719
  1454. 20722 B$ = DESC$
  1455.       EN$ = ALWAYS.STREW.TO$
  1456.       GOSUB 20730
  1457.       EN$ = STREW.TO$
  1458.       GOSUB 20730
  1459. 20725 EN$ = UPLOAD.DIRECTORY$
  1460.       IF FMS.DIRECTORY$ = UPLOAD.DIRECTORY$ THEN _
  1461.          B$ = DESC$ + SPACE$(MAX.DESC.LEN-LEN(DESC$)) + Y$ + SPACE$(3-LEN(Y$))
  1462.       GOSUB 20730
  1463. 20726 Y$ = " >> uploaded << "
  1464.       UPLOADS = UPLOADS + 1
  1465.       CALL MUSIC (7)
  1466.       CALL TIMEREMAIN (TIME.REMAINING!)
  1467.       SECONDS.PER.SESSION! = SECONDS.PER.SESSION! + _
  1468.                              UPLOAD.TIME.FACTOR! * _
  1469.                              (TCA!-Q!)
  1470.       EXIT SUB
  1471. 20730 '          ---[ lock file ]---
  1472.       IF EN$ = "" THEN _
  1473.          RETURN
  1474.       BX = &H4
  1475.       SUBROUTINE.PARAMETER = 9
  1476.       CALL FILELOCK
  1477.       CLOSE 2
  1478.       IF SHARE.IT THEN _
  1479.          OPEN EN$ FOR APPEND SHARED AS #2 _
  1480.       ELSE OPEN "A",2,EN$
  1481.       '          ---[ append ]---
  1482.       PRINT #2,USING "\           \########  &  &"; _
  1483.                      FILE.NAME.HOLD$; _
  1484.                      BYTES.IN.FILE#; _
  1485.                      Z$; _
  1486.                      B$
  1487.       CLOSE 2
  1488.       '          ---[ unlock ]---
  1489.       BX = &H4
  1490.       SUBROUTINE.PARAMETER = 10
  1491.       CALL FILELOCK
  1492.       RETURN
  1493.       END SUB
  1494. ' $SUBTITLE: 'BADFILE - subroutine to find bad file names'
  1495. ' $PAGE
  1496. '
  1497. '  SUBROUTINE NAME    -- BADFILE
  1498. '
  1499. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  1500. '                        VIOLATION$
  1501. '                        VIOLATIONS.THIS.SESSION
  1502. '                        FILNAME$                      NAME OF FILE
  1503. '
  1504. '  OUTPUT PARAMETERS  -- RESULT                      1 = FILE NAME IS OK
  1505. '                                                    2 = CHARACTER NOT ALLOWED
  1506. '                                                    3 = SYSTEM CRASH ATTEMPT
  1507. '                        VIOLATIONS.THIS.SESSION     NUMBER OF VIOLATIONS
  1508. '                        FILNAME$                    Gets capitalized
  1509. '
  1510. '  SUBROUTINE PURPOSE -- TO PROTECT RBBS-PC AGAINST THE USE OF BAD FILE NAMES
  1511. '                        TO EITHER CRASH THE SYSTEM OR TO BREACH RBBS-PC'S
  1512. '                        SECURITY
  1513. '
  1514.       SUB BADFILE (FILNAME$,RESULT) STATIC
  1515. '
  1516. ' *****************************************************************************
  1517. ' *  TEST FOR INVALID CHARACTERS IN FILENAME                                  *
  1518. ' *****************************************************************************
  1519. '
  1520. 20741 RESULT = 1
  1521.       IF LEN(FILNAME$) < 1 THEN _
  1522.          RESULT = 2 : _
  1523.          EXIT SUB
  1524.       CALL ALLCAPS (FILNAME$)
  1525.       IF INSTR(FILNAME$,"?") OR _
  1526.          INSTR(FILNAME$,"*") OR _
  1527.          INSTR(FILNAME$," ") OR _
  1528.          INSTR(3,FILNAME$,":") OR _
  1529.          INSTR(FILNAME$,".DEF") OR _
  1530.          INSTR(FILNAME$,".OLD") OR _
  1531.          MID$(FILNAME$,LEN(FILNAME$),1) = "." THEN _
  1532.            RESULT = 2 : _
  1533.            EXIT SUB
  1534.       FF = INSTR(FILNAME$,".")
  1535.       IF FF > 0 THEN _
  1536.          FF = INSTR(FF+1,FILNAME$,".") : _
  1537.          IF FF > 0 THEN _
  1538.             RESULT = 2 : _
  1539.             EXIT SUB
  1540.       FF = LEN(FILNAME$)
  1541.       IF FF >= 3 THEN _
  1542.          IF INSTR("PRN:CON:AUX:NUL:",FILNAME$) THEN _
  1543.             GOTO 20742
  1544.       IF FF >= 4 THEN _
  1545.          IF INSTR("COM1:COM2:LPT1:LPT2:LPT3:SCRN:KYBD:CONS:",FILNAME$) THEN _
  1546.             GOTO 20742
  1547.       IF FF > 12 THEN _
  1548.          RESULT = 2
  1549.       FG = INSTR(FILNAME$,".")
  1550.       IF FG = 0 AND FF > 8 THEN _
  1551.          RESULT = 2 _
  1552.       ELSE IF FG > 9 THEN _
  1553.               RESULT = 2
  1554.       EXIT SUB
  1555. 20742 VIOLATIONS.THIS.SESSION = MAXIMUM.VIOLATIONS
  1556.       VIOLATION$ = VIOLATION$ + FILNAME$
  1557.       RESULT = 3
  1558.       END SUB
  1559. ' $SUBTITLE: 'FILELOCK - subroutine to share RBBS-PC files'
  1560. ' $PAGE
  1561. '
  1562. '  SUBROUTINE NAME    -- FILELOCK
  1563. '
  1564. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  1565. '                        SUBROUTINE.PARAMETER = 1 UNLOCK USERS AND MESSAGES
  1566. '                                               2 FLUSH MESSAGE RECORD TO DISK
  1567. '                                                 AND UNLOCK MESSAGES
  1568. '                                               3 LOCK MESSAGE FILE
  1569. '                                               4 UNLOCK MESSAGE FILE
  1570. '                                               5 LOCK USER FILE
  1571. '                                               6 LOCK 4 RECORD BLOCK IN USER
  1572. '                                                 FILE
  1573. '                                               7 UNLOCK USER FILE
  1574. '                                               8 UNLOCK 4 RECORD BLOCK IN USER
  1575. '                                                 FILE
  1576. '                                               9 LOCK UPLOAD DIRECTORY OR
  1577. '                                                 COMMENTS FILE
  1578. '                                              10 UNLOCK UPLOAD DIRECTORY OR
  1579. '                                                 COMMENTS FILE
  1580. '                        ACTIVE.MESSAGE FILE$   NAME OF MESSAGE FILE
  1581. '                        ACTIVE.USER.FILE$      NAME OF USER FILE
  1582. '                        CONFIG.FILE.NAME$      FILE NAME TO FLUSH RECORD FROM
  1583. '                        EN$                    UPLOAD DIRECTORY OR COMMENTS
  1584. '                                               FILE NAME TO LOCK/UNLOCK
  1585. '                        NETWORK.TYPE           TYPE OF NETWORK LOCKING TO USE
  1586. '
  1587. '  OUTPUT PARAMETERS  -- SUBROUTINE.PARAMETER = -1 TERMINATE RBBS-PC IMMEDATELY
  1588. '                        BLK
  1589. '                        LOCK.DRIVE
  1590. '                        LOCK.FILE.NAME$
  1591. '                        LOCK.STATUS$
  1592. '                        MESSAGE.FILE.LOCK
  1593. '                        USER.BLOCK.LOCK
  1594. '                        USER.FILE.LOCK
  1595. '                        USER.FILE.INDEX
  1596. '
  1597. '  SUBROUTINE PURPOSE -- TO LOCK AND UNLOCK THE SHARED RBBS-PC FILES WHEN
  1598. '                        MULTIPLE COPIES OF RBBS-PC ARE SHARING THE SAME
  1599. '                        FILES IN EITHER A MULTI-TASKING DOS ENVIRONMENT OR
  1600. '                        IN A LOCAL AREA NETWORK ENVIRONMENT
  1601.       SUB FILELOCK STATIC
  1602.       ON SUBROUTINE.PARAMETER GOSUB 21995,21996,22000,25000,26000,26500,27000,_
  1603.                                     27500,29000,29500
  1604.       EXIT SUB
  1605. '
  1606. ' *****************************************************************************
  1607. ' *  UNLOCK USERS AND MESSAGES                                                *
  1608. ' *****************************************************************************
  1609. '
  1610. 21995 GOSUB 27000
  1611.       GOSUB 25000
  1612.       RETURN
  1613. '
  1614. ' *****************************************************************************
  1615. ' *  FLUSH MESSAGE FILE DATA TO DISK BY OPENING DUMMY FILE # 1                *
  1616. ' *****************************************************************************
  1617. '
  1618. 21996 CLOSE 1
  1619.       IF SHARE.IT THEN _
  1620.          OPEN CONFIG.FILENAME$ FOR INPUT SHARED AS #1 _
  1621.          ELSE OPEN "I",1,CONFIG.FILENAME$
  1622.       CLOSE 1
  1623. '
  1624. ' *****************************************************************************
  1625. ' *  UNLOCK MESSAGES                                                          *
  1626. ' *****************************************************************************
  1627. '
  1628.       GOSUB 25000
  1629.       RETURN
  1630. '
  1631. ' *****************************************************************************
  1632. ' *  LOCK MESSAGE FILE                                                        *
  1633. ' *****************************************************************************
  1634. '
  1635. 22000 IF MESSAGE.FILE.LOCK = TRUE THEN _
  1636.          RETURN
  1637.       MESSAGE.FILE.LOCK = TRUE
  1638.       MID$(LOCK.STATUS$,1,2) = "LM"
  1639.       SUBROUTINE.PARAMETER = 2
  1640.       CALL LINE25
  1641.       LOCK.FILE.NAME$ = ACTIVE.MESSAGE.FILE$
  1642.       ON NETWORK.TYPE GOTO 22100,22200,22300,22400,22500
  1643.       RETURN
  1644. '
  1645. ' *****************************************************************************
  1646. ' *  LOCK MESSAGE FILE (MULTI-LINK)                                           *
  1647. ' *****************************************************************************
  1648. '
  1649. 22100 AX = &H0
  1650.       BX = &H1
  1651.       CALL RBBSML(AX,BX)
  1652.       RETURN
  1653. '
  1654. ' *****************************************************************************
  1655. ' *  LOCK MESSAGE FILE (OMNINET)                                              *
  1656. ' *****************************************************************************
  1657. '
  1658. 22200 CC$ = CHR$(1) + MID$(ACTIVE.MESSAGE.FILE$ + SPACE$(8),3,8)
  1659.       GOSUB 28000
  1660.       IF CT = 0 THEN _
  1661.          RETURN
  1662.       CALL DELAYIT (1)
  1663.       GOTO 22200
  1664. '
  1665. ' *****************************************************************************
  1666. ' *  LOCK MESSAGE FILE (ORCHID PC-NET)                                        *
  1667. ' *  LOCK USER FILE (ORCHID PC-NET)                                           *
  1668. ' *  LOCK UPLOAD DIRECTORY OR COMMENTS BASED ON EN$ (ORCHID PC-NET)           *
  1669. ' *****************************************************************************
  1670. '
  1671. 22300 GOSUB 28100
  1672.       CALL LPLKIT(LOCK.DRIVE,LOCK.FILE.NAME$,A)
  1673.       RETURN
  1674. '
  1675. ' *****************************************************************************
  1676. ' *  LOCK SYSTEM (DESQview)                                                   *
  1677. ' *****************************************************************************
  1678. '
  1679. 22400 AX = 1
  1680.       BX = 0
  1681.       CALL RBBSDV(AX,BX)
  1682.       RETURN
  1683. '
  1684. ' *****************************************************************************
  1685. ' *  LOCK MESSAGE FILE (10 NET)                                               *
  1686. ' *  LOCK USER FILE (10 NET)                                                  *
  1687. ' *  LOCK UPLOAD DIRECTORY OR COMMENTS BASED ON EN$ (10 NET)                  *
  1688. ' *****************************************************************************
  1689. '
  1690. 22500 GOSUB 28100
  1691.       CALL LPLK10(LOCK.DRIVE,LOCK.FILE.NAME$,A)
  1692.       RETURN
  1693. '
  1694. ' *****************************************************************************
  1695. ' *  UNLOCK MESSAGE FILE                                                      *
  1696. ' *****************************************************************************
  1697. '
  1698. 25000 MESSAGE.FILE.LOCK = FALSE
  1699.       MID$(LOCK.STATUS$,1,2) = "UM"
  1700.       SUBROUTINE.PARAMETER = 2
  1701.       CALL LINE25
  1702.       LOCK.FILE.NAME$ = ACTIVE.MESSAGE.FILE$
  1703.       ON NETWORK.TYPE GOTO 25100,25200,25300,25400,25500
  1704.       RETURN
  1705. '
  1706. ' *****************************************************************************
  1707. ' *  UNLOCK MESSAGE FILE (MULTI-LINK)                                         *
  1708. ' *****************************************************************************
  1709. '
  1710. 25100 AX = &H100
  1711.       BX = &H1
  1712.       CALL RBBSML(AX,BX)
  1713.       RETURN
  1714. '
  1715. ' *****************************************************************************
  1716. ' *  UNLOCK MESSAGE FILE (OMNINET)                                            *
  1717. ' *****************************************************************************
  1718. '
  1719. 25200 CC$ = CHR$(17) + MID$(ACTIVE.MESSAGE.FILE$ + SPACE$(8),3,8)
  1720.       GOSUB 28000
  1721.       IF CT = 128 THEN _
  1722.          RETURN
  1723.       CALL DELAYIT (1)
  1724.       GOTO 25200
  1725. '
  1726. ' *****************************************************************************
  1727. ' *  UNLOCK MESSAGE FILE (ORCHID PC-NET)                                      *
  1728. ' *  UNLOCK USER FILE (ORCHID PC-NET)                                         *
  1729. ' *  UNLOCK UPLOAD DIRECTORY OR COMMENTS BASED ON EN$ (ORCHID PC-NET)         *
  1730. ' *****************************************************************************
  1731. '
  1732. 25300 GOSUB 28100
  1733.       CALL UNLOKIT(LOCK.DRIVE,LOCK.FILE.NAME$,A)
  1734.       RETURN
  1735. '
  1736. ' *****************************************************************************
  1737. ' *  UNLOCK SYSTEM (DESQview)                                                 *
  1738. ' *****************************************************************************
  1739. '
  1740. 25400 AX = 2
  1741.       BX = 0
  1742.       CALL RBBSDV(AX,BX)
  1743.       RETURN
  1744. '
  1745. ' *****************************************************************************
  1746. ' *  UNLOCK MESSAGE FILE (10 NET)                                             *
  1747. ' *  UNLOCK USER FILE (10 NET)                                                *
  1748. ' *  UNLOCK UPLOAD DIRECTORY OR COMMENTS BASED ON EN$ (10 NET)                *
  1749. ' *****************************************************************************
  1750. '
  1751. 25500 GOSUB 28100
  1752.       CALL UNLOK10(LOCK.DRIVE,LOCK.FILE.NAME$,A)
  1753.       RETURN
  1754.  
  1755. '
  1756. ' *****************************************************************************
  1757. ' *  LOCK USER FILE                                                           *
  1758. ' *****************************************************************************
  1759. '
  1760. 26000 IF USER.FILE.LOCK = TRUE THEN _
  1761.          RETURN
  1762.       USER.FILE.LOCK = TRUE
  1763.       MID$(LOCK.STATUS$,4,2) = "LU"
  1764.       SUBROUTINE.PARAMETER = 2
  1765.       CALL LINE25
  1766.       LOCK.FILE.NAME$ = ACTIVE.USER.FILE$
  1767.       ON NETWORK.TYPE GOTO 26100,26200,22300,22400,22500
  1768.       RETURN
  1769. '
  1770. ' *****************************************************************************
  1771. ' *  LOCK USER FILE (MULTI-LINK)                                              *
  1772. ' *****************************************************************************
  1773. '
  1774. 26100 AX = &H0
  1775.       BX = &H2
  1776.       CALL RBBSML(AX,BX)
  1777.       RETURN
  1778. '
  1779. ' *****************************************************************************
  1780. ' *  LOCK USER FILE (OMNINET)                                                 *
  1781. ' *****************************************************************************
  1782. '
  1783. 26200 CC$ = CHR$(1) + MID$(ACTIVE.USER.FILE$ + SPACE$(8),3,8)
  1784.       GOSUB 28000
  1785.       IF CT = 0 THEN _
  1786.          RETURN
  1787.       CALL DELAYIT (1)
  1788.       GOTO 26200
  1789. '
  1790. ' *****************************************************************************
  1791. ' *  LOCK 4 RECORD BLOCK IN USER FILE                                         *
  1792. ' *****************************************************************************
  1793. '
  1794. 26500 IF USER.BLOCK.LOCK = TRUE THEN _
  1795.          RETURN
  1796.       USER.BLOCK.LOCK = TRUE
  1797.       BLK = (USER.FILE.INDEX / 4) + .26
  1798.       MID$(LOCK.STATUS$,7,2) = "LB"
  1799.       SUBROUTINE.PARAMETER = 2
  1800.       CALL LINE25
  1801.       ON NETWORK.TYPE GOTO 26600,26700,26800,22400,26900
  1802.       RETURN
  1803. '
  1804. ' *****************************************************************************
  1805. ' *  LOCK 4 RECORD BLOCK IN USER FILE (MULTI-LINK)                            *
  1806. ' *****************************************************************************
  1807. '
  1808. 26600 AX = &H0
  1809.       BX = BLK + 10
  1810.       CALL RBBSML(AX,BX)
  1811.       RETURN
  1812. '
  1813. ' *****************************************************************************
  1814. ' *  LOCK 4 RECORD BLOCK IN USER FILE (OMNINET)                               *
  1815. ' *****************************************************************************
  1816. '
  1817. 26700 CC$ = CHR$(1) + "BLK" + RIGHT$("0000" + MID$(STR$(BLK),2),5)
  1818.       GOSUB 28000
  1819.       IF CT = 0 THEN _
  1820.          RETURN
  1821.       CALL DELAYIT (1)
  1822.       GOTO 26700
  1823. '
  1824. ' *****************************************************************************
  1825. ' *  LOCK 4 RECORD BLOCK IN USER FILE (ORCHID PC-NET)                         *
  1826. ' *****************************************************************************
  1827. '
  1828. 26800 LOCK.FILE.NAME$ = LEFT$(ACTIVE.USER.FILE$,2) + "BLK" + RIGHT$("0000" + MID$(STR$(BLK),2),5)
  1829.       GOTO 22300
  1830. '
  1831. ' *****************************************************************************
  1832. ' *  LOCK 4 RECORD BLOCK IN USER FILE (10 NET)                                *
  1833. ' *****************************************************************************
  1834. '
  1835. 26900 LOCK.FILE.NAME$ = LEFT$(ACTIVE.USER.FILE$,2) + "BLK" + RIGHT$("0000" + MID$(STR$(BLK),2),5)
  1836.       GOTO 22500
  1837. '
  1838. ' *****************************************************************************
  1839. ' *  UNLOCK USER FILE                                                         *
  1840. ' *****************************************************************************
  1841. '
  1842. 27000 USER.FILE.LOCK = FALSE
  1843.       MID$(LOCK.STATUS$,4,2) = "UU"
  1844.       SUBROUTINE.PARAMETER = 2
  1845.       CALL LINE25
  1846.       LOCK.FILE.NAME$ = ACTIVE.USER.FILE$
  1847.       ON NETWORK.TYPE GOTO 27100,27200,25300,25400,25500
  1848.       RETURN
  1849. '
  1850. ' *****************************************************************************
  1851. ' *  UNLOCK USER FILE (MULTI-LINK)                                            *
  1852. ' *****************************************************************************
  1853. '
  1854. 27100 AX = &H100
  1855.       BX = &H2
  1856.       CALL RBBSML(AX,BX)
  1857.       RETURN
  1858. '
  1859. ' *****************************************************************************
  1860. ' *  UNLOCK USER FILE (OMNINET)                                               *
  1861. ' *****************************************************************************
  1862. '
  1863. 27200 CC$ = CHR$(17) + MID$(ACTIVE.USER.FILE$ + SPACE$(8),3,8)
  1864.       GOSUB 28000
  1865.       IF CT = 128 THEN _
  1866.          RETURN
  1867.       CALL DELAYIT (1)
  1868.       GOTO 27200
  1869.  
  1870. '
  1871. ' *****************************************************************************
  1872. ' *  UNLOCK 4 RECORD BLOCK IN USER FILE                                       *
  1873. ' *****************************************************************************
  1874. '
  1875. 27500 USER.BLOCK.LOCK = FALSE
  1876.       BLK = (USER.FILE.INDEX / 4) + .26
  1877.       MID$(LOCK.STATUS$,7,2) = "UB"
  1878.       SUBROUTINE.PARAMETER = 2
  1879.       CALL LINE25
  1880.       ON NETWORK.TYPE GOTO 27600,27700,27800,25400,27900
  1881.       RETURN
  1882. '
  1883. ' *****************************************************************************
  1884. ' *  UNLOCK 4 RECORD BLOCK IN USER FILE (MULTI-LINK)                          *
  1885. ' *****************************************************************************
  1886. '
  1887. 27600 AX = &H100
  1888.       BX = BLK + 10
  1889.       CALL RBBSML(AX,BX)
  1890.       RETURN
  1891. '
  1892. ' *****************************************************************************
  1893. ' *  UNLOCK 4 RECORD BLOCK IN USER FILE (OMNINET)                             *
  1894. ' *****************************************************************************
  1895. '
  1896. 27700 CC$ = CHR$(17) + "BLK" + RIGHT$("0000" + MID$(STR$(BLK),2),5)
  1897.       GOSUB 28000
  1898.       IF CT = 128 THEN _
  1899.          RETURN
  1900.       CALL DELAYIT (1)
  1901.       GOTO 27700
  1902. '
  1903. ' *****************************************************************************
  1904. ' *  UNLOCK 4 RECORD BLOCK IN USER FILE (ORCHID PC-NET)                       *
  1905. ' *****************************************************************************
  1906. '
  1907. 27800 LOCK.FILE.NAME$ = LEFT$(ACTIVE.USER.FILE$,2) + "BLK" + RIGHT$("0000" + MID$(STR$(BLK),2),5)
  1908.       GOTO 25300
  1909. '
  1910. ' *****************************************************************************
  1911. ' *  UNLOCK 4 RECORD BLOCK IN USER FILE (ORCHID PC-NET)                       *
  1912. ' *****************************************************************************
  1913. '
  1914. 27900 LOCK.FILE.NAME$ = LEFT$(ACTIVE.USER.FILE$,2) + "BLK" + RIGHT$("0000" + MID$(STR$(BLK),2),5)
  1915.       GOTO 25500
  1916. '
  1917. ' *****************************************************************************
  1918. ' *  CORVUS OMNINET INTERFACE                                                 *
  1919. ' *****************************************************************************
  1920. '
  1921. 28000 CC$ = LINE.FEED$ + CHR$(0) + CHR$(11) + CC$
  1922.       CALL CDSEND(CC$)
  1923.       CALL CDRECV(CN$)
  1924.       CT = ASC(MID$(CN$,3,1))
  1925.       IF CT >= 128 THEN _
  1926.          PRINT "CORVUS LOCK FAIL" : _
  1927.          SUBROUTINE.PARAMETER = -1
  1928. 28010 CT = ASC(MID$(CN$,4,1))
  1929.       IF CT >= 129 THEN _
  1930.          PRINT "CORVUS FULL" : _
  1931.          SUBROUTINE.PARAMETER = -1
  1932.       RETURN
  1933. '
  1934. ' *****************************************************************************
  1935. ' *  ORCHID PC-NET & 10 NET INTERFACE                                         *
  1936. ' *****************************************************************************
  1937. '
  1938. 28100 CALL ALLCAPS (LOCK.FILE.NAME$)
  1939.       LOCK.DRIVE = ASC(LEFT$(LOCK.FILE.NAME$,1))-ASC("A")
  1940.       LOCK.FILE.NAME$ = LOCK.FILE.NAME$ + _
  1941.                         STRING$(32-LEN(LOCK.FILE.NAME$),0)
  1942.       A = 0
  1943.       RETURN
  1944. '
  1945. ' *****************************************************************************
  1946. ' *  LOCK UPLOAD DIRECTORY OR COMMENTS BASED ON EN$                           *
  1947. ' *****************************************************************************
  1948. '
  1949. 29000 MID$(LOCK.STATUS$,10,2) = "LD"
  1950.       SUBROUTINE.PARAMETER = 2
  1951.       CALL LINE25
  1952.       LOCK.FILE.NAME$ = EN$
  1953.       ON NETWORK.TYPE GOTO 29100,29010,22300,22400,22500
  1954. 29010 RETURN
  1955. '
  1956. ' *****************************************************************************
  1957. ' *  LOCK UPLOAD DIRECTORY OR COMMENTS BASED ON EN$ (MULTI-LINK)              *
  1958. ' *****************************************************************************
  1959. '
  1960. 29100 AX = &H0
  1961.       BX = &H3
  1962.       CALL RBBSML(AX,BX)
  1963.       RETURN
  1964. '
  1965. ' *****************************************************************************
  1966. ' *  UNLOCK UPLOAD DIRECTORY OR COMMENTS BASED ON EN$                         *
  1967. ' *****************************************************************************
  1968. '
  1969. 29500 MID$(LOCK.STATUS$,10,2) = "UD"
  1970.       SUBROUTINE.PARAMETER = 2
  1971.       CALL LINE25
  1972.       LOCK.FILE.NAME$ = EN$
  1973.       ON NETWORK.TYPE GOTO 29600,29510,25300,25400,25500
  1974. 29510 RETURN
  1975. '
  1976. ' *****************************************************************************
  1977. ' *  UNLOCK UPLOAD DIRECTORY OR COMMENTS BASED ON EN$ (MULTI-LINK)            *
  1978. ' *****************************************************************************
  1979. '
  1980. 29600 AX = &H100
  1981.       BX = &H3
  1982.       CALL RBBSML(AX,BX)
  1983.       EXIT SUB
  1984.       END SUB
  1985. ' $SUBTITLE: 'OPENMSG - open the MESSAGES file'
  1986. ' $PAGE
  1987. '
  1988. '  SUBROUTINE NAME    -- OPENMSG
  1989. '
  1990. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  1991. '                         ACTIVE.MESSAGE.FILE$
  1992. '                         SHARE.IT
  1993. '
  1994. '  OUTPUT PARAMETERS  --  MESSAGE.RECORD$
  1995. '
  1996.       SUB OPENMSG STATIC
  1997. '
  1998. ' *****************************************************************************
  1999. ' *  OPEN AND DEFINE MESSAGE FILE                                             *
  2000. ' *****************************************************************************
  2001. '
  2002. 30500 CLOSE 1
  2003.       IF SHARE.IT THEN _
  2004.          OPEN ACTIVE.MESSAGE.FILE$ FOR RANDOM SHARED AS #1 _
  2005.       ELSE OPEN "R",1,ACTIVE.MESSAGE.FILE$
  2006.       FIELD 1,128 AS MESSAGE.RECORD$
  2007.       END SUB
  2008. ' $SUBTITLE: 'TIMEREMAIN - calculates time remaining in a session'
  2009. ' $PAGE
  2010. '
  2011. '  SUBROUTINE NAME    -- TIMEREMAIN
  2012. '
  2013. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2014. '                         USER.LOGON.TIME!
  2015. '                         SECONDS.PER.SESSION!
  2016. '                         BYPASS.TIME.CHECK
  2017. '  OUTPUT PARAMETERS  --     PARAMETER                    MEANING
  2018. '                         TIME.REMAINING! TIME IN MINUTES LEFT IN SESSION
  2019. '                         TCA!            TIME USED IN SECONDS
  2020.       SUB TIMEREMAIN (TIME.REMAINING!) STATIC
  2021. 41010 TOA! = FRE("A")
  2022.       IF BYPASS.TIME.CHECK THEN _
  2023.          TIME.REMAINING! = SECONDS.PER.SESSION! : _
  2024.          EXIT SUB
  2025.       CALL FINDTIME (TI!)
  2026.       IF TI! > USER.LOGON.TIME! THEN _
  2027.          CALL FINDTIME (TCA!) : _
  2028.          TCA! = TCA! - USER.LOGON.TIME! _
  2029.       ELSE CALL FINDTIME (TI!) : _
  2030.            TCA! = TI! + 86400! - USER.LOGON.TIME!
  2031.       TIME.REMAINING! = (SECONDS.PER.SESSION!-TCA!) / 60
  2032.       TIME.REMAINING! = -(TIME.REMAINING! > 0.0)*TIME.REMAINING!
  2033.       END SUB
  2034. '
  2035. ' *****************************************************************************
  2036. ' * SUBROUTINE TO CALCULATE AND DISPLAY THE TIME REAMINING                    *
  2037. ' *****************************************************************************
  2038. '
  2039.       SUB DISPLAYTR (TIME.REMAINING!) STATIC
  2040.       CALL TIMEREMAIN (TIME.REMAINING!)
  2041.       CALL QTPUT (STR$(INT(TIME.REMAINING!))+" min left",1)
  2042.       END SUB
  2043. ' $SUBTITLE: 'AMORPM - subroutine to give time of day in AM/PM format'
  2044. ' $PAGE
  2045. '
  2046. '  SUBROUTINE NAME    -- AMORPM
  2047. '
  2048. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2049. '                        SUBROUTINE.PARAMETER = 1  GET CURRENT TIME AND DATE
  2050. '                        SUBROUTINE.PARAMETER = 2  CALCULATE TIME AS AM OR PM
  2051. '
  2052. '  OUTPUT PARAMETERS  -- CURRENT.DATE$           CURRENT DATE (MM-DD-YY)
  2053. '                        TIM$                    CURRENT TIME (I.E. 1:13 PM)
  2054. '                        TIME.LOGGEND.ON$        TIME USER LOGGED ON (HH:MM:SS)
  2055. '
  2056. '  SUBROUTINE PURPOSE -- TO SET THE OUTPUT PARAMETERS AS INDICATED AND
  2057. '                        DESCRIBE THE TIME AS "AM" OR "PM."
  2058. '
  2059.       SUB AMORPM STATIC
  2060.       ON SUBROUTINE.PARAMETER GOTO 41500,41510
  2061. '
  2062. ' *****************************************************************************
  2063. ' *  CALCULATE CURRENT TIME FOR AM OR PM                                      *
  2064. ' *****************************************************************************
  2065. '
  2066. 41500 TIME.LOGGED.ON$ = TIME$
  2067.       CURRENT.DATE$ = LEFT$(DATE$ ,6) + RIGHT$(DATE$ ,2)
  2068. 41510 TIM$ = TIME$
  2069.       IF VAL(MID$(TIM$,1,2)) = 12 THEN _
  2070.          MID$(TIM$,1,2) = RIGHT$(STR$(VAL(MID$(TIM$,1,2))),2) : _
  2071.          TIM$ = LEFT$(TIM$,5) + " PM" : _
  2072.          EXIT SUB
  2073.       IF VAL(MID$(TIM$,1,2)) > 11 THEN _
  2074.          MID$(TIM$,1,2) = RIGHT$(STR$(VAL(MID$(TIM$,1,2))-12),2) : _
  2075.          TIM$ = LEFT$(TIM$,5) + " PM" : _
  2076.          EXIT SUB
  2077.       TIM$ = LEFT$(TIM$,5) + " AM"
  2078.       END SUB
  2079. ' $SUBTITLE: 'CARRIER - subroutine to monitor carrier on comm. port'
  2080. ' $PAGE
  2081. '
  2082. '  SUBROUTINE NAME    -- CARRIER
  2083. '
  2084. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2085. '                         LOCAL.USER = 0               REMOTE USER
  2086. '                         LOCAL.USER = -1              LOCAL KEYBOARD USER
  2087. '                         MODEM.STATUS.REGISTER        ADDRESS OF THE COMMUNI-
  2088. '                                                      CATIONS PORT'S REGISTER
  2089. '                         SUBROUTINE.PARAMETER = -9    DON'T WRITE TO CALLERS
  2090. '                         SUBROUTINE.PARAMETER = -10   SAME AS -9, BUT DON'T
  2091. '                                                      DELAY
  2092. '
  2093. '  OUTPUT PARAMETERS  --  SUBROUTINE.PARAMETER = 0     CARRIER STILL PRESENT
  2094. '                         SUBROUTINE.PARAMETER = -1    CARRIER NOT PRESENT
  2095. '
  2096. '  SUBROUTINE PURPOSE --  TO TEST IF CARRIER IS PRESENT (I.E. THE USER
  2097. '                         STILL ON LINE).
  2098. '
  2099.       SUB CARRIER STATIC
  2100.       TOA! = FRE("A")
  2101.       IF SUBROUTINE.PARAMETER = -1 THEN _
  2102.          EXIT SUB
  2103.       SPEEDY = 0
  2104.       IF SUBROUTINE.PARAMETER <= -9 THEN _
  2105.      DONT.WRITE = -9
  2106.       IF SUBROUTINE.PARAMETER = -10 THEN _
  2107.      SPEEDY = -1
  2108.       SUBROUTINE.PARAMETER = 0
  2109. '
  2110. ' *****************************************************************************
  2111. ' * TEST FOR CARRIER PRESENT (DROP CALLER IF CARRIER NOT PRESENT)             *
  2112. ' *****************************************************************************
  2113. '
  2114. 42000 IF LOCAL.USER THEN _
  2115.          EXIT SUB
  2116. 42010 IF INP(MODEM.STATUS.REGISTER) > 127 THEN _
  2117.          EXIT SUB
  2118. '
  2119. ' *****************************************************************************
  2120. ' * IN CASE USER IS 2400 BAUD, PAUSE A SECOND AND CHECK AGAIN FOR CARRIER     *
  2121. ' * DETECT.  SOME 2400 BAUD MODEMS TAKE A WHILE TO SYNCHRONIZE THE CARRIER,   *
  2122. ' * HENCE A THREE-SECOND PAUSE BEFORE CHECKING AGAIN.                         *
  2123. ' *****************************************************************************
  2124. '
  2125.       IF SPEEDY = -1 THEN _
  2126.      GOTO 42020
  2127.       CALL DELAYIT (MODEM.INIT.WAIT.TIME)
  2128.       SUBROUTINE.PARAMETER = 0
  2129.       IF INP(MODEM.STATUS.REGISTER) > 127 THEN _
  2130.          EXIT SUB
  2131. 42020 SUBROUTINE.PARAMETER = -1
  2132.       IF DONT.WRITE = -9 THEN _
  2133.      DONT.WRITE = 0 : _
  2134.          EXIT SUB
  2135.       IF ALREADY.WRITTEN = -9 THEN _
  2136.          EXIT SUB
  2137.       CALL MODEMPUT (MODEM.GO.OFFHOOK.COMMAND$)
  2138.       ALREADY.WRITTEN = -9
  2139.       CALL UPDTCALR ("Carrier dropped",1)
  2140.       SUBROUTINE.PARAMETER = -1
  2141.       END SUB
  2142. '
  2143. ' $SUBTITLE: 'GRAPHIC - subroutine to find graphic version of a file'
  2144. ' $PAGE
  2145. '
  2146. '  SUBROUTINE NAME    -- GRAPHIC
  2147. '
  2148. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2149. '                            DEFAULT$          Users graphic default
  2150. '                            GR                Whether graphics avail
  2151. '                            FILE.NAME$        File to check
  2152. '
  2153. '  OUTPUT PARAMETERS  --     FILE.NAME$        Substitutes name of graphics
  2154. '                                              file if it exists
  2155. '
  2156. '  SUBROUTINE PURPOSE -- Checks whether there is a graphics version of
  2157. '                        a file, based on users graphics preference.
  2158. '                        Sets file name to graphics file if it exists,
  2159. '                        otherwise leaves file name intact.  Returns file
  2160. '                        name to use.
  2161. '
  2162.       SUB GRAPHIC (DEFAULT$) STATIC
  2163. 43031 IF GR THEN _
  2164.          CALL BRKFNAME (FILE.NAME$,DR$,X$,EXTENTION$,TRUE) : _
  2165.          IF LEN(X$) < 8 THEN _
  2166.             DF$ = DR$ + _
  2167.                   X$ + _
  2168.                   DEFAULT$ + _
  2169.                   EXTENTION$ : _
  2170.              CALL FINDIT (DF$): _
  2171.              IF OK THEN _
  2172.                 FILE.NAME$ = DF$
  2173.       END SUB
  2174. ' $SUBTITLE: 'SAVEPROF - subroutine to read a user profile'
  2175. ' $PAGE
  2176. '
  2177. '  SUBROUTINE NAME    -- SAVEPROF
  2178. '
  2179. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2180. '                        BPS
  2181. '                        EIGHT.BIT
  2182. '                        EXIT.TO.DOORS
  2183. '                        GR
  2184. '                        KERMIT.FUNCTION
  2185. '                        MESSAGE.RECORD$
  2186. '                        NODE.RECORD.INDEX
  2187. '                        SYSOP
  2188. '                        UPPER.CASE
  2189. '                        TIME.LOGGED.ON$
  2190. '                        PRIVATE.DOOR
  2191. '                        RELIABLE.MODE
  2192. '
  2193. '  OUTPUT PARAMETERS  -- NONE
  2194. '
  2195. '  SUBROUTINE PURPOSE -- SAVES A USER'S OPTIONS AND COMMUNICATIONS PARAMETERS
  2196. '                        IN THE NODE RECORD WHEN A USER EXITS TO A "DOOR" SO
  2197. '                        THAT HE IS IN THE SAME STATUS AS WHEN HE EXITED.
  2198. '
  2199.       SUB SAVEPROF(IPARM) STATIC
  2200.       ON IPARM GOTO 43070,43080
  2201. '
  2202. ' *****************************************************************************
  2203. ' *  SAVE USER PROFILE WHEN EXITING                                           *
  2204. ' *****************************************************************************
  2205. '
  2206. 43070 SUBROUTINE.PARAMETER = 3
  2207.       CALL FILELOCK
  2208.       CALL OPENMSG
  2209.       FIELD 1, 128 AS MESSAGE.RECORD$
  2210.       GET 1,NODE.RECORD.INDEX
  2211.       MID$(MESSAGE.RECORD$,40,2) = STR$(EXIT.TO.DOORS)
  2212.       MID$(MESSAGE.RECORD$,42,2) = STR$(EIGHT.BIT)
  2213.       MID$(MESSAGE.RECORD$,44,2) = STR$(BPS)
  2214.       MID$(MESSAGE.RECORD$,46,2) = STR$(UPPER.CASE)
  2215.       MID$(MESSAGE.RECORD$,48,5) = SPACE$(5)
  2216.       MID$(MESSAGE.RECORD$,53,2) = STR$(GR)
  2217.       MID$(MESSAGE.RECORD$,55,2) = STR$(SYSOP)
  2218.       MID$(MESSAGE.RECORD$,64,8) = TIME.LOGGED.ON$
  2219.       MID$(MESSAGE.RECORD$,72,2) = STR$(PRIVATE.DOOR)
  2220.       MID$(MESSAGE.RECORD$,74,2) = STR$(TRANSFER.FUNCTION)
  2221.       MID$(MESSAGE.RECORD$,91,2) = STR$(RELIABLE.MODE)
  2222. 43080 PUT 1,NODE.RECORD.INDEX
  2223.       SUBROUTINE.PARAMETER = 2
  2224.       CALL FILELOCK
  2225.       CALL OPENMSG
  2226.       END SUB
  2227. ' $SUBTITLE: 'READPROF - subroutine to restore a user profile'
  2228. ' $PAGE
  2229. '
  2230. '  SUBROUTINE NAME    -- READPROF
  2231. '
  2232. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2233. '                        NODE.RECORD.INDEX     NODE RECORD TO USE
  2234. '                        SYSOP.PASSWORD.1$     SYSOP'S PSEUDONYM 1
  2235. '                        SYSOP.PASSWORD.2$     SYSOP'S PSEUDONYM 2
  2236. '
  2237. '  OUTPUT PARAMETERS  -- USER'S OPTIONS AND COMMUNICATIONS PARAMETERS
  2238. '                        UPON EXITING RBBS-PC TO A "DOOR"
  2239. '
  2240. '  SUBROUTINE PURPOSE -- RESET A USER'S OPTIONS AND COMMUNICATIONS PARAMETERS
  2241. '                        THAT WERE SAVED IN THE NODE RECORD WHEN A USER EXITED
  2242. '                        TO A "DOOR" SO THAT HE IS IN THE SAME STATUS AS WHEN
  2243. '                        HE EXITED.
  2244. '
  2245.       SUB READPROF STATIC
  2246. '
  2247. ' *****************************************************************************
  2248. ' *  RESTORE USER PROFILE WHEN RETURNING FROM DOORS                           *
  2249. ' *****************************************************************************
  2250. '
  2251. 44000 LOCATE 24,1
  2252.       PRINT "NODE INDEX", NODE.RECORD.INDEX
  2253.       FIELD 1, 128 AS MESSAGE.RECORD$
  2254.       GET 1,NODE.RECORD.INDEX
  2255.       EIGHT.BIT = VAL(MID$(MESSAGE.RECORD$,42,2))
  2256.       RELIABLE.MODE = VAL(MID$(MESSAGE.RECORD$,91,2))
  2257.       BPS = VAL(MID$(MESSAGE.RECORD$,44,2))
  2258.       CALL COMMINFO
  2259.       BAUD.TEST = VAL(LEFT$(BAUD.PARITY$,4))
  2260.       UPPER.CASE = VAL(MID$(MESSAGE.RECORD$,46,2))
  2261.       GR = VAL(MID$(MESSAGE.RECORD$,53,2))
  2262.       SYSOP = VAL(MID$(MESSAGE.RECORD$,55,2))
  2263.       TIME.LOGGED.ON$ = MID$(MESSAGE.RECORD$,64,8)
  2264.       PRIVATE.DOOR = VAL(MID$(MESSAGE.RECORD$,72,2))
  2265.       TRANSFER.FUNCTION = VAL(MID$(MESSAGE.RECORD$,74,2))
  2266.       IF REQUIRED.RINGS > 0 AND _
  2267.          INSTR(MODEM.INIT.COMMAND$,"S0=255") THEN _
  2268.          COLOR 7,0,0 _
  2269.       ELSE COLOR FG,BG,BORDER
  2270.       IF LOCAL.USER.MODE THEN _
  2271.          GOTO 44003
  2272.       IF BPS = -1 THEN _
  2273.          BAUD.RATE.DIVISOR = &H180 + (11*(COMPUTER.TYPE = 2))
  2274.       IF BPS = -2 THEN _
  2275.          BAUD.RATE.DIVISOR = &H100 + (8*(COMPUTER.TYPE = 2))
  2276.       IF BPS = -3 THEN _
  2277.          BAUD.RATE.DIVISOR = &H60 + (3*(COMPUTER.TYPE = 2))
  2278.       IF BPS = -4 THEN _
  2279.          BAUD.RATE.DIVISOR = &H30 + (1*(COMPUTER.TYPE = 2))
  2280.       IF BPS = -5 THEN _
  2281.          BAUD.RATE.DIVISOR = &H18
  2282.       IF BPS = -6 THEN _
  2283.          BAUD.RATE.DIVISOR = &HC
  2284.       CALL SETBAUD
  2285. 44003 CALL FINDTIME (USER.LOGON.TIME!)
  2286.       IF MINUTES.PER.SESSION! < 1 THEN _
  2287.          MINUTES.PER.SESSION! = 3
  2288.       IF NOT EIGHT.BIT THEN _
  2289.          OUT LINE.CONTROL.REGISTER,&H1A
  2290.       IF SYSOP THEN _
  2291.          FIRST.NAME$ = SYSOP.PASSWORD.1$ : _
  2292.          LAST.NAME$ = SYSOP.PASSWORD.2$ : _
  2293.          ACTIVE.USER.NAME$ = MID$(FIRST.NAME$ + _
  2294.                              " " + LAST.NAME$,1,31) : _
  2295.          EXIT SUB
  2296.       FIRST.NAME.END = INSTR(MESSAGE.RECORD$," ")
  2297.       LAST.NAME.END = INSTR(FIRST.NAME.END + 1,MESSAGE.RECORD$," ")
  2298.       FIRST.NAME$ = LEFT$(MESSAGE.RECORD$,FIRST.NAME.END-1)
  2299.       LAST.NAME$ = MID$(MESSAGE.RECORD$,FIRST.NAME.END + 1,LAST.NAME.END-(FIRST.NAME.END + 1))
  2300.       ACTIVE.USER.NAME$ = MID$(FIRST.NAME$ + " " + LAST.NAME$,1,31)
  2301.       Z$ = FIRST.NAME$
  2302.       END SUB
  2303. ' $SUBTITLE: 'COMMINFO - subroutine for variable of users baud/parity'
  2304. ' $PAGE
  2305. '
  2306. '  SUBROUTINE NAME    -- COMMINFO
  2307. '
  2308. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2309. '                              BPS               BAUD RATE INDICATOR
  2310. '                            EIGHT.BIT           INDICATE FOR N/8/1
  2311. '
  2312. '  OUTPUT PARAMETERS  -- BAUD.PARITY$
  2313. '
  2314. '  SUBROUTINE PURPOSE -- CREATE A STRING THAT SHOWS A USERS BAUD RATE AND
  2315. '                        PARITY.
  2316. '
  2317.       SUB COMMINFO STATIC
  2318. '
  2319. ' *****************************************************************************
  2320. ' *  DETERMINE BAUD AND PARITY                                                *
  2321. ' *****************************************************************************
  2322. '
  2323.   IF RELIABLE.MODE THEN _
  2324.      RELIABLE.MODE$ = "-R," _
  2325.   ELSE RELIABLE.MODE$ = ","
  2326.   BAUD.PARITY$ = MID$("    300 4501200240048009600",(-4*BPS),4) + _
  2327.                  " BAUD" + _
  2328.                  RELIABLE.MODE$ + _
  2329.                  MID$("N,8,1E,7,1",6 + 5*EIGHT.BIT,5)
  2330.   END SUB
  2331. ' $SUBTITLE: 'DELAYIT - subroutine to wait number of seconds specified'
  2332. ' $PAGE
  2333. '
  2334. '  SUBROUTINE NAME    -- DELAYIT
  2335. '
  2336. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2337. '                             DELAY.TIME           NUMBER OF SECONDS TO DELAY
  2338. '                                                  (0 TO 3,600)
  2339. '
  2340. '  OUTPUT PARAMETERS  -- NONE
  2341. '
  2342. '  SUBROUTINE PURPOSE -- TO WAIT THE NUMBER OF SECONDS INDICATED BEFORE
  2343. '                        RETURNING CONTROL TO THE CALLING ROUTINE.
  2344. '
  2345.       SUB DELAYIT (DELAY.TIME) STATIC
  2346.       IF DELAY.TIME < 1 THEN _
  2347.          EXIT SUB
  2348.       CALL FINDTIME (DELAY!)
  2349.       DELAY! = DELAY.TIME + DELAY!
  2350.       IF DELAY! < 86400! THEN _
  2351.          GOTO 50520
  2352. 50500 CALL FINDTIME (TI!)
  2353.       IF TI! > DELAY.TIME THEN _  ' IF SECONDS TO DELAY IS PAST
  2354.          GOTO 50500              ' MIDNIGHT WAIT FOR THE CLOCK TO WRAP AROUND
  2355.       DELAY! = DELAY! - 86400!   ' TO PAST MIDNIGHT AND ADJUST THE DELAY
  2356. 50520 CALL FINDTIME (TI!)
  2357.       IF TI! < DELAY! THEN _
  2358.          GOTO 50520
  2359.       END SUB
  2360. ' $SUBTITLE: 'MODEMPUT - subroutine to write modem commands to modem'
  2361. ' $PAGE
  2362. '
  2363. '  SUBROUTINE NAME    -- MODEMPUT
  2364. '
  2365. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  2366. '                        STRNG$                    MODEM COMMAND
  2367. '                        COMMANDS.BETWEEN.RINGS    INDICATOR TO WAIT FOR
  2368. '                                                  MODEM TO STOP RINGING
  2369. '                                                  BEFORE ISSUING COMMANDS
  2370. '                        DUMB.MODEM                INDICATOR THAT MODEM WOULD
  2371. '                                                  NOT UNDERSTAND COMMANDS
  2372. '
  2373. '  OUTPUT PARAMETERS  -- NONE
  2374. '
  2375. '  SUBROUTINE PURPOSE -- TO ISSUE MODEM COMMANDS TO THE MODEM
  2376. '
  2377.       SUB MODEMPUT (STRNG$) STATIC
  2378. '
  2379. ' *****************************************************************************
  2380. ' *  SEND MODEM COMMAND                                                       *
  2381. ' *****************************************************************************
  2382. '
  2383. 52070 IF DUMB.MODEM THEN _
  2384.          EXIT SUB
  2385.       IF NOT COMMANDS.BETWEEN.RINGS OR _
  2386.      NOT (INP(MODEM.STATUS.REGISTER) AND &H40) THEN _
  2387.      GOTO 52080
  2388.       CALL FINDTIME (CONNECT.DELAY!)
  2389.       CONNECT.DELAY! = CONNECT.DELAY! + 7
  2390. 52072 IF (INP(MODEM.STATUS.REGISTER) AND &H40) > 0 THEN _
  2391.      CALL FINDTIME (TI!) : _
  2392.      IF TI! > CONNECT.DELAY! OR _
  2393.         (ABS(CONNECT.DELAY! - TI!) > 30 AND _
  2394.          (TI! + 86400 > CONNECT.DELAY!)) THEN _
  2395.         GOTO 52080
  2396.       GOTO 52072
  2397. 52080 CALL DELAYIT (MODEM.COMMAND.DELAY.TIME)
  2398.       PRINT #3,STRNG$
  2399.       END SUB
  2400. ' $SUBTITLE: 'FINDFUNC - subroutine to find if function key was pressed'
  2401. ' $PAGE
  2402. '
  2403. '  SUBROUTINE NAME    -- FINDFUNC
  2404. '
  2405. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2406. '                        F1.KEY           FUNCTION KEY ONE VALUE
  2407. '                        F10.KEY          FUNCTION KEY TEN VALUE
  2408. '
  2409. '  OUTPUT PARAMETERS  -- FUNCTION.KEY (VALUE 1 TO 10 CORRESPONDING TO
  2410. '                                      THE FUNCTION KEY THAT WAS PRESSED).
  2411. '                        KEY.PRESSED$ (CHARACTER STRING INPUTTED).
  2412. '
  2413. '  SUBROUTINE PURPOSE -- TO DETERMINE IF A FUNCTION HAS BEEN PRESSED ON
  2414. '                        THE PC'S KEYBOARD THAT IS RUNNING RBBS-PC.
  2415. '
  2416.       SUB FINDFUNC STATIC
  2417. '
  2418. ' *****************************************************************************
  2419. ' *  TEST FOR FUNCTION KEY PRESSED                                            *
  2420. ' *****************************************************************************
  2421. '
  2422. 58040 KEY.PRESSED$ = INKEY$
  2423.       FUNCTION.KEY = 0
  2424.       IF LEN(KEY.PRESSED$) <> 2 THEN _
  2425.          EXIT SUB
  2426.       KEY.PRESSED = ASC(RIGHT$(KEY.PRESSED$,1))
  2427.       IF LOCAL.USER.MODE THEN _
  2428.          KEY.PRESSED$ = "" : _
  2429.          EXIT SUB
  2430.       IF KEY.PRESSED >= F1.KEY AND _
  2431.          KEY.PRESSED <= F10.KEY THEN _
  2432.              FUNCTION.KEY = KEY.PRESSED - 58:_
  2433.              EXIT SUB
  2434.       IF KEY.PRESSED = 79 THEN _     'End
  2435.          FUNCTION.KEY = 11 : _
  2436.          EXIT SUB
  2437.       IF KEY.PRESSED = 72 THEN _     'up arrow
  2438.          CALL CARRIER : _
  2439.          IF SUBROUTINE.PARAMETER = -1 THEN _
  2440.             EXIT SUB _
  2441.          ELSE ADJUSTED.SECURITY = TRUE : _
  2442.               USER.SECURITY.LEVEL = USER.SECURITY.LEVEL + 1: _
  2443.               SUBROUTINE.PARAMETER = 2: _
  2444.               CALL LINE25: _
  2445.               CALL CALLOPT : _
  2446.               EXIT SUB
  2447.       IF KEY.PRESSED = 73 THEN _     'PgUp
  2448.          FUNCTION.KEY = 12 : _
  2449.          EXIT SUB
  2450.       IF KEY.PRESSED = 80 THEN _     'Down arrow
  2451.          CALL CARRIER : _
  2452.          IF SUBROUTINE.PARAMETER = -1 THEN _
  2453.             EXIT SUB_
  2454.          ELSE ADJUSTED.SECURITY = TRUE:_
  2455.               USER.SECURITY.LEVEL = USER.SECURITY.LEVEL - 1: _
  2456.               SUBROUTINE.PARAMETER = 2: _
  2457.               CALL LINE25: _
  2458.               CALL CALLOPT : _
  2459.               EXIT SUB
  2460.       END SUB
  2461. ' $SUBTITLE: 'FINDTIME - subroutine to calculate seconds since midnight'
  2462. ' $PAGE
  2463. '
  2464. '  SUBROUTINE NAME    -- FINDTIME
  2465. '
  2466. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2467. '                            SECONDS!          VARIABLE TO RETURN RESULTS WITH
  2468. '
  2469. '  OUTPUT PARAMETERS  --     SECONDS!          SECONDS SINCE MIDNIGHT
  2470. '
  2471. '  SUBROUTINE PURPOSE -- TO CALCULATE THE NUMBER OF SECONDS THAT HAVE
  2472. '                        ELASPED SINCE MIDNIGHT
  2473. '
  2474.       SUB FINDTIME (SECONDS!) STATIC
  2475. 58050 SECONDS! = TIMER
  2476.       END SUB
  2477. ' $SUBTITLE: 'ALLCAPS - subroutine to convert string to upper case'
  2478. ' $PAGE
  2479. '
  2480. '  SUBROUTINE NAME    -- ALLCAPS
  2481. '
  2482. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2483. '                            CONVERT.FIELD$    STRING TO MAKE UPPER CASE
  2484. '
  2485. '  OUTPUT PARAMETERS  --     CONVERT.FIELD$    CONVERTED STRINGS
  2486. '
  2487. '  SUBROUTINE PURPOSE -- SUBROUTINE TO CONVERT A STRING TO UPPER CASE
  2488. '
  2489.       SUB ALLCAPS (CONVERT.FIELD$) STATIC
  2490. 58060 IF TURBO.RBBS THEN _
  2491.          CALL RBBSULC (CONVERT.FIELD$) : _
  2492.          EXIT SUB
  2493.       FOR Z = 1 TO LEN(CONVERT.FIELD$)
  2494.           IF MID$(CONVERT.FIELD$,Z,1) > "@" THEN _
  2495.              MID$(CONVERT.FIELD$,Z,1) = CHR$(ASC(MID$(CONVERT.FIELD$,Z,1)) AND 223)
  2496.       NEXT
  2497.       END SUB
  2498. ' $SUBTITLE: 'ALLCAPSD - subroutine to convert string to upper case'
  2499. ' $PAGE
  2500. '
  2501. '  SUBROUTINE NAME    -- ALLCAPSD
  2502. '
  2503. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2504. '                            CONVERT.FIELD$    DIMENSIONED STRING TO MAKE
  2505. '                                              UPPER CASE
  2506. '
  2507. '  OUTPUT PARAMETERS  --     CONVERT.FIELD$    CONVERTED STRINGS
  2508. '
  2509. '  SUBROUTINE PURPOSE -- SUBROUTINE TO CONVERT A STRING TO UPPER CASE
  2510. '
  2511.       SUB ALLCAPSD (CONVERT.FIELD$(1),CONVERT.INDEX) STATIC
  2512. 58065 IF TURBO.RBBS THEN _
  2513.          CALL RBBSULC (CONVERT.FIELD$(CONVERT.INDEX)) : _
  2514.          EXIT SUB
  2515.       FOR Z = 1 TO LEN(CONVERT.FIELD$(CONVERT.INDEX))
  2516.           IF MID$(CONVERT.FIELD$(CONVERT.INDEX),Z,1) > "@" THEN _
  2517.              MID$(CONVERT.FIELD$(CONVERT.INDEX),Z,1) = CHR$(ASC(MID$(CONVERT.FIELD$(CONVERT.INDEX),Z,1)) AND 223)
  2518.       NEXT
  2519.       END SUB
  2520. ' $SUBTITLE: 'CHECKTIM - subroutine to see if time has elasped'
  2521. ' $PAGE
  2522. '
  2523. '  SUBROUTINE NAME    -- CHECKTIM
  2524. '
  2525. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2526. '                            MAX.TIME!         NUMBER OF SECONDS PAST MIDNIGHT
  2527. '                                              NOT TO EXCEED
  2528. '
  2529. '  OUTPUT PARAMETERS  -- SUBROUTINE.PARAMETER = 1 CURRENT TIME IS LESS THAN
  2530. '                                                 MAX.TIME!
  2531. '                        SUBROUTINE.PARAMETER = 2 CURRENT TIME IS GREATER THAN
  2532. '                                                 OR EQUAL TO MAX.TIME!
  2533. '
  2534. '  SUBROUTINE PURPOSE -- SUBROUTINE TO CHECK IF THE CURRENT TIME IS GREATER
  2535. '                        THAN OR EQUAL TO THE TIME ALLOWED
  2536. '
  2537.       SUB CHECKTIM (MAX.TIME!) STATIC
  2538. 58070 SUBROUTINE.PARAMETER = 1
  2539.       CALL FINDTIME (TI!)
  2540.       IF MAX.TIME! < 86400 AND TI! < MAX.TIME! THEN _
  2541.          EXIT SUB
  2542.       IF MAX.TIME! < 86400 AND TI! => MAX.TIME! THEN _
  2543.          SUBROUTINE.PARAMETER = 2 : _
  2544.          EXIT SUB
  2545.       TEST.TIME! = MAX.TIME! - 86400
  2546.       IF TEST.TIME! - TI! <= 0 THEN _
  2547.          EXIT SUB
  2548.       IF TI! => TEST.TIME! THEN _
  2549.          SUBROUTINE.PARAMETER = 2
  2550.       END SUB
  2551. ' $SUBTITLE: 'HASHRBBS - subroutine to determine where to look for user'
  2552. ' $PAGE
  2553. '
  2554. '  SUBROUTINE NAME    -- HASHRBBS
  2555. '
  2556. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2557. '                            STRNG.TO.HASH$    USER NAME TO LOCATE
  2558. '                            MAX.POSITION      MAXIMUM # USERS
  2559. '
  2560. '  OUTPUT PARAMETERS  --     PRIME.HASH        WHERE TO LOOK FIRST
  2561. '                            SECOND.HASH       LOOK THIS FAR AHEAD
  2562. '
  2563. '  SUBROUTINE PURPOSE -- WHERE TO LOOK FOR A USER IN USERS FILE
  2564. '                        LOOK FIRST AT PRIME POSITION, THEN ADD
  2565. '                        SECOND.HASH UNTIL FIND OR FIND UNUSED RECORD
  2566. '
  2567.       SUB HASHRBBS (STRNG.TO.HASH$,MAX.POSITION,PRIME.HASH,SECOND.HASH) STATIC
  2568. 58080 SECOND.HASH = (ASC(MID$(STRNG.TO.HASH$,2,1))*10  + 7) MOD _
  2569.            MAX.POSITION
  2570.       PRIME.HASH = _
  2571.            ((ASC(STRNG.TO.HASH$)*100  + _
  2572.              ASC(MID$(STRNG.TO.HASH$,LEN(STRNG.TO.HASH$) / 2,1)) * _
  2573.              10  + _
  2574.              ASC(RIGHT$(STRNG.TO.HASH$,1))) _
  2575.              MOD MAX.POSITION) + 1
  2576.       END SUB
  2577. ' $SUBTITLE: 'CALLOPT - subroutine to set prompts based on user security'
  2578. ' $PAGE
  2579. '
  2580. '  SUBROUTINE NAME    -- CALLOPT
  2581. '
  2582. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2583. '                            BEG.MAIN          POSITION START OF MAIN CMDS
  2584. '                            BEG.FILE          POSITION START OF FILE CMDS
  2585. '                            BEG.UTIL          POSITION START OF UTIL CMDS
  2586. '
  2587. '  OUTPUT PARAMETERS  -- PRESENT.OPTS$         DISPLAY WHAT USER CAN DO (1st)
  2588. '                        CALLERS.OPTS$         DISPLAY WHAT USER CAN DO (2nd)
  2589. '                        MAIN.OPTS$            MAIN OPTS USER CAN DO
  2590. '                        FILE.OPTS$            FILE OPTS USER CAN DO
  2591. '                        UTIL.OPTS$            UTIL OPTS USER CAN DO
  2592. '
  2593. '  SUBROUTINE PURPOSE -- SETS COMMAND LINE DISPLAY OF WHAT USER CAN DO BY
  2594. '                        SECTION AND DISPLAY OF WHAT ALL USER CAN DO
  2595. '
  2596.       SUB CALLOPT STATIC
  2597. 58090 FIRST = BEG.MAIN
  2598.       LAST = BEG.FILE - 1
  2599.       CALL SETOPTS (MAIN.OPTS$,FIRST,LAST)
  2600.       FIRST = BEG.FILE
  2601.       LAST = BEG.UTIL - 1
  2602.       CALL SETOPTS (FILE.OPTS$,FIRST,LAST)
  2603.       FIRST = BEG.UTIL
  2604.       LAST = BEG.UTIL + 10
  2605.       CALL SETOPTS (UTIL.OPTS$,FIRST,LAST)
  2606.       FIRST = 40
  2607.       LAST = 46
  2608.       CALL SETOPTS (SYS.OPTS$,FIRST,LAST)
  2609.       FIRST = 36
  2610.       LAST = 39
  2611.       CALL SETOPTS (GLOBAL.OPTS$,FIRST,LAST)
  2612.       PRESENT.OPTS$ = "Your valid commands are:"
  2613.       IF LEN(GLOBAL.OPTS$) > 0 THEN _
  2614.           PRESENT.OPTS$ = PRESENT.OPTS$ + " Globals: " + GLOBAL.OPTS$
  2615.       CALLERS.OPTS$ = "Main: " + MAIN.OPTS$ + _
  2616.                       " File: " + FILE.OPTS$ + _
  2617.                       " Util: " + UTIL.OPTS$
  2618.       IF LEN(SYS.OPTS$)>0 THEN _
  2619.          CALLERS.OPTS$ = CALLERS.OPTS$ + " Sysop: " + SYS.OPTS$
  2620.       MAIN.OPTS$ = GLOBAL.OPTS$ + MAIN.OPTS$
  2621.       FILE.OPTS$ = GLOBAL.OPTS$ + FILE.OPTS$
  2622.       UTIL.OPTS$ = GLOBAL.OPTS$ + UTIL.OPTS$
  2623.       CALL SRTSTRNG (SYS.OPTS$)
  2624.       CALL SRTSTRNG (MAIN.OPTS$)
  2625.       MAIN.OPTS$ = MAIN.OPTS$ + SYS.OPTS$
  2626.       CALL SRTSTRNG (FILE.OPTS$)
  2627.       CALL SRTSTRNG (UTIL.OPTS$)
  2628.       CALL INSCOMMA (MAIN.OPTS$)
  2629.       CALL INSCOMMA (FILE.OPTS$)
  2630.       CALL INSCOMMA (UTIL.OPTS$)
  2631.       DIR.PROMPT$ = "What directories (" + _
  2632.                     MID$("<U>pload,<A>ll,[ENTER] ", _
  2633.                     9*(USER.SECURITY.LEVEL >= MIN.SEC.TO.VIEW)+10)
  2634.       END SUB
  2635. ' $SUBTITLE: 'SETOPTS - subroutine to set prompts based on user security'
  2636. ' $PAGE
  2637. '
  2638. '  SUBROUTINE NAME    -- SETOPTS
  2639. '
  2640. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2641. '                            FIRST             POSITION WHERE START LOOKING
  2642. '                            LAST              POSITION WHERE QUIT LOOKING
  2643. '                            USER.SECURITY.LEVEL SECURITY OF USER
  2644. '
  2645. '  OUTPUT PARAMETERS  -- OPTIONS$              LIST OF COMMANDS USER CAN DO
  2646. '
  2647. '  SUBROUTINE PURPOSE -- STRING TOGETHER WHAT COMMANDS USER CAN DO
  2648. '                        IN A SECTION
  2649. '
  2650.       SUB SETOPTS (OPTIONS$,FIRST,LAST) STATIC
  2651. 58100 OPTIONS$ = ""
  2652.       FOR I = FIRST TO LAST
  2653.          IF USER.SECURITY.LEVEL >= OPT.SEC(I) THEN _
  2654.             IF MID$(ALL.OPTS$,I,1) <> " " THEN _
  2655.                OPTIONS$ = OPTIONS$ + MID$(ALL.OPTS$,I,1)
  2656.       NEXT
  2657.       CALL SRTSTRNG (OPTIONS$)
  2658.       END SUB
  2659. ' $SUBTITLE: 'CHKNEWBUL - subroutine to check whether got new bulletins'
  2660. ' $PAGE
  2661. '
  2662. '  SUBROUTINE NAME    -- CHKNEWBUL
  2663. '
  2664. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2665. '                            LAST.ON$          Last date of logon
  2666. '                                                format mm/dd/yy
  2667. '                            ACTIVE.BULLETINS  # of bulletins
  2668. '                            BULLETIN.PREFIX$  Filespec for bulletins
  2669. '
  2670. '  OUTPUT PARAMETERS  --     NUM.NEW.BULLETS   Number of new bulletins
  2671. '                            NEW.BULLETS$      List of new bullet #'s
  2672. '                            Q                 where last bulletin stored
  2673. '                                                 in B$()
  2674. '                            B$()              Bulletins #'s that are new
  2675. '                                                 (2,3,4,...)
  2676. '  SUBROUTINE PURPOSE -- Checks how many bulletins have system date
  2677. '                        at or later than date caller last logged on
  2678. '
  2679.       SUB CHKNEWBUL (LAST.ON$,NUM.NEW.BULLETS,NEW.BULLETS$) STATIC
  2680. 58110 NUM.NEW.BULLETS = 0
  2681.       NEW.BULLETS$ = ":  "
  2682.       BASE.DATE# = VAL(MID$(LAST.ON$,4,2)) + (100 * VAL(MID$(LAST.ON$,1,2))) + _
  2683.                    (10000# * (1900 + VAL(MID$(LAST.ON$,7,2))))
  2684.       FOR I = 1 TO ACTIVE.BULLETINS
  2685.          Y$ = MID$(STR$(I),2)
  2686.          X$ = BULLETIN.PREFIX$ + Y$ + CHR$(0)
  2687.      CALL RBBSFIND (X$,IX,YY,MM,DD)
  2688.      IF IX = 0 THEN _
  2689.             FDATE# = DD + (100 * MM) + (10000# * (YY+1980)) : _
  2690.             IF BASE.DATE# <= FDATE# THEN _
  2691.                NUM.NEW.BULLETS = NUM.NEW.BULLETS + 1 : _
  2692.                B$(NUM.NEW.BULLETS+1) = Y$ : _
  2693.                NEW.BULLETS$ = NEW.BULLETS$ + " " + Y$
  2694.       NEXT
  2695.       Q = NUM.NEW.BULLETS+1
  2696.       IF NUM.NEW.BULLETS < 1 THEN _
  2697.          NEW.BULLETS$ = ""
  2698.       END SUB
  2699. ' $SUBTITLE: 'SRTSTRNG - subroutine to sort characters in a string'
  2700. ' $PAGE
  2701. '
  2702. '  SUBROUTINE NAME    -- SRTSTRNG
  2703. '
  2704. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2705. '                              STRNG$           String to sort
  2706. '
  2707. '  OUTPUT PARAMETERS  --     STRNG$             Sorted string
  2708. '
  2709. '  SUBROUTINE PURPOSE -- Sorts characters in passed string.
  2710. '
  2711.       SUB SRTSTRNG (STRNG$) STATIC
  2712. 58120 S0 = LEN(STRNG$)
  2713.       S1 = S0
  2714.       X$ = "!"
  2715. 58122 S1 = S1\2
  2716.       IF S1 = 0 THEN _
  2717.          EXIT SUB
  2718.       S2 = S0 - S1
  2719.       FOR S3 = 1 TO S2
  2720.          S4 = S3
  2721. 58124    S5 = S4 + S1
  2722.          IF MID$(STRNG$,S4,1) > MID$(STRNG$,S5,1) THEN _
  2723.             LSET X$ = MID$(STRNG$,S4,1):_
  2724.             MID$(STRNG$,S4,1) = MID$(STRNG$,S5,1):_
  2725.             MID$(STRNG$,S5,1) = X$: _
  2726.             S4 = S4 - S1:_
  2727.             IF S4 > 0 THEN _
  2728.                GOTO 58124
  2729.       NEXT
  2730.       GOTO 58122
  2731.       END SUB
  2732. ' $SUBTITLE: 'INSCOMMA - subroutine to format commands in command prompt'
  2733. ' $PAGE
  2734. '
  2735. '  SUBROUTINE NAME    -- INSCOMMA
  2736. '
  2737. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2738. '                              STRNG$           String to replace
  2739. '
  2740. '  OUTPUT PARAMETERS  --     STRNG$             Replaced string
  2741. '
  2742. '  SUBROUTINE PURPOSE -- Inserts commands between each letter in STRNG$
  2743. '                        and encloses in pointed brackets
  2744.       SUB INSCOMMA (STRNG$) STATIC
  2745. 58130 L = LEN(STRNG$)
  2746.       IF L < 1 THEN _
  2747.          EXIT SUB
  2748.       LSET LINEMES$ = " <" + LEFT$(STRNG$,1)
  2749.       FOR K = 2 TO L
  2750.          MID$(LINEMES$,2*K,2) = "," + MID$(STRNG$,K,1)
  2751.       NEXT
  2752.       STRNG$ = LEFT$(LINEMES$,2*L+1) + ">"
  2753.       END SUB
  2754. ' $SUBTITLE: 'LOADNEW - subroutine to get latest uploads'
  2755. ' $PAGE
  2756. '
  2757. '  SUBROUTINE NAME    -- LOADNEW
  2758. '
  2759. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2760. '                          UPLOAD.DIRECTORY$  List of files uploaded
  2761. '
  2762. '  OUTPUT PARAMETERS  --     A$                Latest uploads
  2763. '
  2764. '  SUBROUTINE PURPOSE -- Loads table of most recent number of uploads
  2765. '                        by date
  2766.       SUB LOADNEW (ARA(2)) STATIC
  2767. 58140 IF FMS.DIRECTORY$ = "" THEN _
  2768.          EXIT SUB
  2769.       CALL OPENFMS (LAST.REC)
  2770.       FIELD 2, 23 AS PRE.DATE$,_
  2771.                 2 AS MM$,_
  2772.                 1 AS FILL1$,_
  2773.                 2 AS DD$,_
  2774.                 1 AS FILL2$,_
  2775.                 2 AS YY$,_
  2776.                 (2+MAX.DESC.LEN) AS FILL3$,_
  2777.                 3 AS CATEGORY$, _
  2778.                 2 AS FILL4$
  2779.       MAX.RECS = UBOUND(ARA,1)
  2780.       IF MAX.RECS < 1 THEN_
  2781.          MAX.RECS = 1 _
  2782.       ELSE IF MAX.RECS > 23 THEN _
  2783.               MAX.RECS = 23
  2784.       L = 0
  2785.       K = LAST.REC
  2786.       WHILE K > 0 AND L < MAX.RECS
  2787.          GET #2,K
  2788.          IF (CAN.DOWNLOAD.FROM.UP OR CATEGORY$ <> DEFAULT.CATEGORY.CODE$) THEN _
  2789.             L = L+1:_
  2790.             ARA(L,1) = 366*(VAL(YY$)-80)+31*VAL(MM$)+VAL(DD$)
  2791.          IF NOT CAN.DOWNLOAD.FROM.UP THEN _
  2792.             X = MIN.SEC.TO.VIEW _
  2793.          ELSE IF CATEGORY$ = "***" THEN _
  2794.                  X = SYSOP.SECURITY.LEVEL _
  2795.               ELSE IF CATEGORY$ = DEFAULT.CATEGORY.CODE$ THEN _
  2796.                       X = MIN.SEC.TO.VIEW _
  2797.                    ELSE_
  2798.                        X = OPT.SEC(18)
  2799.          ARA(L,2) = X
  2800.          K = K - 1
  2801.       WEND
  2802.       CLOSE 2
  2803.       END SUB
  2804. ' $SUBTITLE: 'CTNEWFILES - subroutine to count how many files new'
  2805. ' $PAGE
  2806. '
  2807. '  SUBROUTINE NAME    -- CTNEWFILES
  2808. '
  2809. '  INPUT PARAMETERS   --     PARAMETER           MEANING
  2810. '                             LAST.ON$          Date of last logon
  2811. '                             UPLDS$            Latest uploads
  2812. '
  2813. '  OUTPUT PARAMETERS  --    NUM.NEW.FILES       How many after last logon
  2814. '
  2815. '  SUBROUTINE PURPOSE -- CHECKS HOW MANY FILES IN UPLDS$ WERE UPLOADED ON OR
  2816. '                        AFTER DATE OF LAST LOGON THAT THE USER CAN DOWNLOAD
  2817. '
  2818.       SUB CTNEWFILES (LAST.ON$,UPLDS(2),NUM.USER.FILES) STATIC
  2819. 58150 BASE.DATE = 366*(VAL(MID$(LAST.ON$,7,2))-80) + _
  2820.                   31*(VAL(MID$(LAST.ON$,1,2))) + _
  2821.                   VAL(MID$(LAST.ON$,4,2))
  2822.       NUM.NEW.FILES = 1
  2823.       NUM.USER.FILES = 0
  2824.       WHILE (BASE.DATE <= UPLDS(NUM.NEW.FILES,1) AND _
  2825.                 UPLDS(NUM.NEW.FILES,1)>0 AND_
  2826.                 NUM.NEW.FILES < UBOUND(UPLDS,1))
  2827.         IF USER.SECURITY.LEVEL >= UPLDS(NUM.NEW.FILES,2) THEN _
  2828.            NUM.USER.FILES = NUM.USER.FILES + 1
  2829.         NUM.NEW.FILES = NUM.NEW.FILES + 1
  2830.       WEND
  2831.       END SUB
  2832. ' $SUBTITLE: 'CTLINES - subroutine to determine file categories '
  2833. ' $PAGE
  2834. '
  2835. '  SUBROUTINE NAME    -- CTLINES
  2836. '
  2837. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  2838. '                        DIR.CATEGORY.FILE$    NAME OF THE FILE THAT HAS THE
  2839. '                                              NUMBER OF CATEGORIES IN IT.
  2840. '
  2841. '  OUTPUT PARAMETERS  -- MAX.ENTRIES           NUMBER OF FILE CATEGORIES
  2842. '
  2843. '  SUBROUTINE PURPOSE -- SUBROUTINE TO COUNT THE NUMBER OF CATEGORIES THAT A
  2844. '                        FILE CAN BE CLASSIFIED INTO.
  2845. '
  2846.       SUB CTLINES (MAX.ENTRIES) STATIC
  2847. 58160 MAX.ENTRIES = 3
  2848.       CALL FINDIT (DIR.CATEGORY.FILE$)
  2849.       IF OK THEN _
  2850.          WHILE NOT EOF(2):_
  2851.            MAX.ENTRIES = MAX.ENTRIES + 1:_
  2852.            LINE INPUT #2,A$:_
  2853.          WEND
  2854.       CLOSE 2
  2855.       IF MAX.ENTRIES < 10 THEN _
  2856.          MAX.ENTRIES = 10
  2857.       END SUB
  2858. ' $SUBTITLE: 'INITFMS - subroutine to initialize file management system'
  2859. ' $PAGE
  2860. '
  2861. '  SUBROUTINE NAME    -- INITFMS
  2862. '
  2863. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  2864. '                        UPLOAD.DIRECTORY$
  2865. '
  2866. '  OUTPUT PARAMETERS  -- CATEGORY.NAME$(), elements 1,2, possibly more
  2867. '                        CATEGORY.CODE$(), elements 1,2, possibly more
  2868. '                        CATEGORY.DESC$(), elements 1,2, possibly more
  2869. '                        CATEGORY.INDEX count of # elements in upload
  2870. '                           management system
  2871. '
  2872. '  SUBROUTINE PURPOSE -- SUBROUTINE TO INITIALIZE THE RBBS-PC UPLOAD MANAGEMENT
  2873. '                        SYSTEM
  2874.       SUB INITFMS (CATEGORY.NAME$(1),CATEGORY.CODE$(1),_
  2875.                    CATEGORY.DESC$(1),CATEGORY.INDEX) STATIC
  2876.       BLNK$ = " "
  2877.       CATEGORY.INDEX = 0
  2878.       IF FMS.DIRECTORY$ <> "" THEN _
  2879.          CATEGORY.INDEX = CATEGORY.INDEX + 1:_
  2880.          CATN$ = CATEGORY.NAME$(CATEGORY.INDEX) : _
  2881.          CALL BRKFNAME (FMS.DIRECTORY$,DRVPATH$,CATN$,EXTENSION$,FALSE) : _
  2882.          CATEGORY.NAME$(CATEGORY.INDEX) = CATN$ : _
  2883.          CATEGORY.CODE$(CATEGORY.INDEX) = "":_
  2884.          CATEGORY.DESC$(CATEGORY.INDEX) = "All uploads"_
  2885.       ELSE_
  2886.          LIMIT.SEARCH.TO.FMS = FALSE:_
  2887.          EXIT SUB
  2888.       IF LIMIT.SEARCH.TO.FMS THEN _
  2889.          CATEGORY.INDEX = CATEGORY.INDEX + 1 : _
  2890.          CATEGORY.NAME$(CATEGORY.INDEX) = "ALL" : _
  2891.          CATEGORY.CODE$(CATEGORY.INDEX) = "" : _
  2892.          CATEGORY.DESC$(CATEGORY.INDEX) = "All files"
  2893.       CALL FINDIT (DIR.CATEGORY.FILE$)
  2894.       IF NOT OK THEN _
  2895.          EXIT SUB
  2896.       WHILE NOT EOF(2)
  2897.          CATEGORY.INDEX = CATEGORY.INDEX + 1
  2898.          INPUT #2, CATEGORY.NAME$(CATEGORY.INDEX),_
  2899.                    CATEGORY.CODE$(CATEGORY.INDEX),_
  2900.                    CATEGORY.DESC$(CATEGORY.INDEX)
  2901.          CATR$ = CATEGORY.CODE$(CATEGORY.INDEX)
  2902.          CALL REMOVE (CATR$,BLNK$)
  2903.          CATEGORY.CODE$(CATEGORY.INDEX) = CATR$
  2904.       WEND
  2905.       CLOSE 2
  2906.       END SUB
  2907. ' $SUBTITLE: 'DISUPDIR - subroutine to display upload direcotry'
  2908. ' $PAGE
  2909. '
  2910. '  SUBROUTINE NAME    -- DISUPDIR
  2911. '
  2912. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  2913. '                     PASSED.CATEGORIES$    FILE "CATEGORIES" TO BE INCLUDED IN
  2914. '                                           THE SEARCH.
  2915. '                        SEARCH.STRING$     STRING TO SEARCH ON WITHIN THE
  2916. '                                           FILE "CATEGORIES" SELECTED
  2917. '                        SEARCH.DATE$       DATE EQUAL TO OR GREATER THAN TO BE
  2918. '                                           SEARCHED FOR WITH THE "CATEGORIES"
  2919. '                                           AND THE STRING TO SEARCH.
  2920. '                        DOWNLOAD.FLAG      SET TO RECORD # OF LINE TO BEGIN
  2921. '                                           VIEWING - 0 IF AT END
  2922. '
  2923. '  OUTPUT PARAMETERS  -- DOWNLOAD.FLAG      WHENEVER DOWNLOAD REQUESTED, SETS
  2924. '                                           TO NEXT RECORD TO VIEW.  OTHERWISE
  2925. '                                           LEAVES AT ZERO
  2926. '
  2927. '  SUBROUTINE PURPOSE -- DISPLAY THE FILES THAT MEET THE CRITERIA SELECTED IN
  2928. '                        RBBS-PC UPLOAD MANAGEMENT SYSTEM ON THE USERS SCREEN.
  2929. '
  2930.       SUB DISUPDIR (PASSED.CATEGORIES$,SEARCH.STRING$,SEARCH.DATE$,_
  2931.                     DOWNLOAD.FLAG) STATIC
  2932. 58170 CALL ALLCAPS (SEARCH.STRING$)
  2933.       BLNK$ = " "
  2934.       STOP.INTERRUPTS = TRUE
  2935.       CATEGORIES$ = "," + PASSED.CATEGORIES$ + ","
  2936.       CAN.DOWNLOAD = (USER.SECURITY.LEVEL >= OPT.SEC(18))
  2937.       CALL OPENFMS (UPLOAD.INDEX)
  2938.       UPLOAD.INDEX = UPLOAD.INDEX + 1
  2939.       IF DOWNLOAD.FLAG > 0 THEN _
  2940.          UPLOAD.INDEX = DOWNLOAD.FLAG : _
  2941.          DOWNLOAD.FLAG = 0
  2942.       FIELD 2,(33+MAX.DESC.LEN) AS PART.TO.PRINT$,_
  2943.                3 AS CATEGORY$,_
  2944.                2 AS FILLER$
  2945.       MAX.PRINT = PAGE.LENGTH - 1
  2946.       BELOW.MIN.SEC = (USER.SECURITY.LEVEL < MIN.SEC.TO.VIEW)
  2947.       NON.STOP = (PAGE.LENGTH < 1)
  2948.       CHECK.POINT = 0
  2949.       LINES.PRINTED = 0
  2950. 58171 UPLOAD.INDEX = UPLOAD.INDEX - 1
  2951.       IF UPLOAD.INDEX < 1 THEN _
  2952.          GOTO 58177
  2953.       GET #2,UPLOAD.INDEX
  2954. 58172 CHECK.POINT = CHECK.POINT + 1
  2955.       IF CATEGORY$ = "***" THEN _
  2956.          IF NOT SYSOP THEN _
  2957.             GOTO 58176
  2958.       IF CATEGORY$ = DEFAULT.CATEGORY.CODE$ THEN _
  2959.          IF BELOW.MIN.SEC THEN _
  2960.             GOTO 58176
  2961. 58173 IF LEN(CATEGORIES$) > 2 THEN _
  2962.          KEE$ = "," + CATEGORY$ + "," :_
  2963.          CALL REMOVE (KEE$,BLNK$):_
  2964.          IF INSTR(CATEGORIES$,KEE$)=0 THEN _
  2965.             GOTO 58176
  2966.       IF SEARCH.STRING$ <> "" THEN _
  2967.          A$ = PART.TO.PRINT$ : _
  2968.          CALL ALLCAPS (A$) : _
  2969.          IF INSTR (A$,SEARCH.STRING$) = 0 THEN _
  2970.             GOTO 58176
  2971. 58174 IF SEARCH.DATE$ <> "" THEN _
  2972.          KEE$ = MID$(PART.TO.PRINT$,30,2) + _
  2973.                 MID$(PART.TO.PRINT$,24,2) + _
  2974.                 MID$(PART.TO.PRINT$,27,2) : _
  2975.          IF KEE$ < SEARCH.DATE$ THEN _
  2976.             GOTO 58177
  2977. '
  2978. ' *****************************************************************************
  2979. ' * Allow the FMS to be both fast and interruptable if a local                *
  2980. ' * user or there is nothing in the input buffer by using QTPUT.              *
  2981. ' *****************************************************************************
  2982. '
  2983. 58175 IF LOCAL.USER THEN _
  2984.          CALL QTPUT(PART.TO.PRINT$,1) _
  2985.       ELSE _
  2986.          IF EOF(3) THEN _
  2987.             CALL QTPUT(PART.TO.PRINT$,1) : _
  2988.          ELSE _
  2989.             A$ = PART.TO.PRINT$ : _
  2990.             SUBROUTINE.PARAMETER = 1 : _
  2991.             CALL TPUT : _
  2992.             IF RET THEN _
  2993.                GOTO 58177
  2994. 58176 IF LINES.PRINTED <= MAX.PRINT AND CHECK.POINT < 1000 THEN _
  2995.          GOTO 58171
  2996.       CALL CARRIER
  2997.       IF NOT LOCAL.USER AND SUBROUTINE.PARAMETER=-1 THEN _
  2998.          GOTO 58177
  2999.       CALL TIMEREMAIN (TIME.REMAINING!)
  3000.       IF TIME.REMAINING! < 0.1 THEN _
  3001.          SUBROUTINE.PARAMETER = -1 : _
  3002.          GOTO 58177
  3003.       IF NON.STOP THEN _
  3004.          GOTO 58171
  3005.       IF LINES.PRINTED <= MAX.PRINT THEN _
  3006.          CALL QTPUT ("Files checked thru "+MID$(PART.TO.PRINT$,24,8),1)
  3007.       A$ = "MORE: [Y],N,NS" + _
  3008.            LEFT$(", or file(s) to download",-24*CAN.DOWNLOAD)
  3009.       SUBROUTINE.PARAMETER = 1
  3010.       NO.ADVANCE = TRUE
  3011.       CALL TGET
  3012.       IF NOT LOCAL.USER AND SUBROUTINE.PARAMETER = -1 THEN _
  3013.          GOTO 58177
  3014.       IF NO THEN_
  3015.          CALL WIPELINE (42) : _
  3016.          GOTO 58177
  3017.       IF LEN(B$(1))>2 THEN _
  3018.          IF NOT YES AND CAN.DOWNLOAD THEN _
  3019.             CALL SKIPLINE (1) : _
  3020.             DOWNLOAD.FLAG = UPLOAD.INDEX : _
  3021.             EXIT SUB
  3022.       CALL WIPELINE (42)
  3023.       IF NON.STOP THEN IF UPLOAD.INDEX > 999 THEN _
  3024.          IF (SEARCH.DATE$="" OR NOT EXPERT.USER) THEN_
  3025.             A$ = STR$(UPLOAD.INDEX) + _
  3026.                " files left to search.  Really go non-stop? (Y/[N])":_
  3027.             NO.ADVANCE = TRUE : _
  3028.            CALL TGET :_
  3029.            CALL WIPELINE (79) : _
  3030.            IF NOT YES THEN _
  3031.               NON.STOP = FALSE
  3032.       CHECK.POINT = 0
  3033.       GOTO 58171
  3034. 58177 CLOSE 2
  3035.       NON.STOP = (PAGE.LENGTH < 1)
  3036.       STOP.INTERRUPTS = FALSE
  3037.       A$ = ""
  3038.       END SUB
  3039. ' $SUBTITLE: 'CHKNARY - subroutine to check for a string in an array'
  3040. ' $PAGE
  3041. '
  3042. '  SUBROUTINE NAME    -- CHKNARY
  3043. '
  3044. '  INPUT PARAMETERS   -- PARAMETER                      MEANING
  3045. '                        ELEMENT$                THE STRING TO CHECK FOR
  3046. '                        ARRAY$()                THE ARRAY TO BE SEARCHED
  3047. '                        NUM.ENTRIES.TO.SEARCH   NUMBER OF ENTRIES WITHIN IN
  3048. '                                                THE ARRAY TO BE SEARCHED
  3049. '
  3050. '  OUTPUT PARAMETERS  -- IS.IN.ARA               0 = STRING NOT FOUND IN THE
  3051. '                                                    ARRAY SPECIFIED
  3052. '                                                OTHERWISE IT IS THE NUMBER OF
  3053. '                                                ELEMENT WITHIN THE ARRAY THAT
  3054. '                                                WAS FOUND TO MATCH
  3055. '
  3056. '  SUBROUTINE PURPOSE -- SEARCH AN ARRAY FOR A SPECIFIED STRING AND, IF FOUND,
  3057. '                        RETURN THE NUMBER OF THE ELEMENT THAT MATCHED.
  3058. '
  3059.       SUB CHKNARY (ELEMENT$,ARRAY$(1),NUM.ENTRIES.TO.SEARCH,IS.IN.ARA) STATIC
  3060. 58180 IS.IN.ARA = 1
  3061.       CALL ALLCAPS(ELEMENT$)
  3062.       MAX.TRIES = NUM.ENTRIES.TO.SEARCH + 1
  3063.       ARRAY$(MAX.TRIES) = ELEMENT$
  3064.       WHILE ARRAY$(IS.IN.ARA) <> ELEMENT$
  3065.          IS.IN.ARA = IS.IN.ARA + 1
  3066.       WEND
  3067.       IF IS.IN.ARA = MAX.TRIES THEN _
  3068.          IS.IN.ARA = 0
  3069.       END SUB
  3070. ' $SUBTITLE: 'FMS - subroutine to search the upload management system'
  3071. ' $PAGE
  3072. '
  3073. '  SUBROUTINE NAME    -- FMS
  3074. '
  3075. '  INPUT PARAMETERS   -- PARAMETER                      MEANING
  3076. '                        DIR.TO.SEARCH$          RBBS-PC "DIR" CATEGORY TO LOOK
  3077. '                                                FOR
  3078. '                        SEARCH.STRING$          STRING TO SEARCH FOR
  3079. '                        SEARCH.DATE$            DATE TO SEARCH FOR
  3080. '                        CATEGORY.NAME$()
  3081. '                        CATEGORY.CODE$()
  3082. '                        CATEGORY.DESC$()
  3083. '                        CAT.FOUND
  3084. '                        NUM.CATEGORIES
  3085. '
  3086. '  OUTPUT PARAMETERS  -- PROCESSED.IN.FMS
  3087. '                        DOWNLOAD.FLAG
  3088. '
  3089. '  SUBROUTINE PURPOSE -- TO SEARCH THE UPLOAD MANAGMENT SYSTEM AND DISPLAY THE
  3090. '                        FILES BEING SEARCHED FOR AS WELL AS THE CATEGORY DE-
  3091. '                        SCRIPTIONS
  3092. '
  3093.       SUB FMS (DIR.TO.SEARCH$,SEARCH.STRING$,SEARCH.DATE$,_
  3094.                PROCESSED.IN.FMS,CATEGORY.NAME$(1),CATEGORY.CODE$(1),_
  3095.                CATEGORY.DESC$(1),DOWNLOAD.FLAG,CAT.FOUND) STATIC
  3096. 58200 DOWNLOAD.FLAG = 0
  3097.       CALL CHKNARY (DIR.TO.SEARCH$,CATEGORY.NAME$(),NUM.CATEGORIES,CAT.FOUND)
  3098.       IF CAT.FOUND > 0 THEN _
  3099.          SUBROUTINE.PARAMETER = 5 : _
  3100.          GOSUB 58202 : _
  3101.          A$ = "Scanning directory " + DIR.TO.SEARCH$ + HDR$ + _
  3102.               " - " + CATEGORY.DESC$(CAT.FOUND) : _
  3103.          CALL TPUT : _
  3104.          CAT$ = CATEGORY.CODE$(CAT.FOUND) : _
  3105.          CALL DISUPDIR (CAT$,SEARCH.STRING$,SEARCH.DATE$,DOWNLOAD.FLAG)
  3106.       PROCESSED.IN.FMS = (CAT.FOUND > 0)
  3107.       EXIT SUB
  3108. 58202 A$ = SEARCH.DATE$
  3109.       IF LEN(A$) > 0 THEN _
  3110.          A$ = MID$(A$,3) + LEFT$(A$,2)
  3111.       HDR$ = " for " + SEARCH.STRING$ + A$
  3112.       IF LEN(HDR$) < 6 THEN _
  3113.          HDR$ = ""
  3114.       RETURN
  3115.       END SUB
  3116. ' $SUBTITLE: 'REMOVE - subroutine to delete a string from within a string'
  3117. ' $PAGE
  3118. '
  3119. '  SUBROUTINE NAME    -- REMOVE
  3120. '
  3121. '  INPUT PARAMETERS   -- PARAMETER                      MEANING
  3122. '                        BADSTRING$              STRING CONTAINING CHARACTERS
  3123. '                                                TO BE DELETED FROM "L$"
  3124. '                        L$                      STRING TO BE ALTERED
  3125. '
  3126. '  OUTPUT PARAMETERS  -- L$                      WITH THE CHARACTERS IN
  3127. '                                                "BADSTRING#" DELETED FROM IT
  3128. '
  3129. '  SUBROUTINE PURPOSE -- TO REMOVE ALL INSTANCES OF THE CHARACTERS IN
  3130. '                        "BADSTRING$" FROM "L$"
  3131. '
  3132.       SUB REMOVE (L$,BADSTRNG$) STATIC
  3133. 58210 J = 0
  3134.       FOR I=1 TO LEN(L$)
  3135.          IF INSTR(BADSTRNG$,MID$(L$,I,1)) = 0 THEN_
  3136.             J = J+1:_
  3137.             MID$(L$,J,1) = MID$(L$,I,1)
  3138.       NEXT I
  3139.       L$ = LEFT$(L$,J)
  3140.       END SUB
  3141. ' $SUBTITLE: 'BUFSTRNG - subroutine to write a string with imbedded CR/LF'
  3142. ' $PAGE
  3143. '
  3144. '  SUBROUTINE NAME    -- BUFSTRNG
  3145. '
  3146. '  INPUT PARAMETERS   -- PARAMETER                      MEANING
  3147. '                        STRNG$                  STRING TO BE WRITTEN OUT
  3148. '                        DATA.SIZE               LENGTH OF STRING - # LEFT
  3149. '                                                    CHARS TO OUTPUT
  3150. '
  3151. '  OUTPUT PARAMETERS  -- STRNG$                  IS WRITTEN TO THE USER
  3152. '
  3153. '  SUBROUTINE PURPOSE -- TO SEARCH THE STRING, STRNG$, FOR IMBEDDED CARRIAGE
  3154. '                        RETURNS AND LINE FEEDS AND WRITE OUT EACH LINE WITH
  3155. '                        THE APPROPRIATE SUBSTITUTION (CR/LF IF TO THE LOCAL
  3156. '                        SCREEN OR CR/NULLS/LF IF TO THE COMMUNICATIONS PORT).
  3157. '
  3158. 58300 SUB BUFSTRNG (STRNG$,DATA.SIZE) STATIC
  3159.       FF = PAGE.LENGTH - 1
  3160.       START.BYTE = 1 - (ASC(STRNG$)=10)
  3161.       IF LEN(STRNG$) < 1 THEN _
  3162.          EXIT SUB
  3163. 58301 CRAT = INSTR(START.BYTE,STRNG$,CARRIAGE.RETURN$)
  3164.       CR.FOUND = (CRAT > 0)
  3165.       EOL.LEN = -2 * CR.FOUND
  3166.       IF CR.FOUND THEN _
  3167.      EOD = CRAT _                                                ' @FORMAT
  3168.       ELSE EOD = DATA.SIZE + 1
  3169.       NUM.BYTES = EOD - START.BYTE
  3170.       CALL QTPUT (MID$(STRNG$,START.BYTE,NUM.BYTES),-(CR.FOUND))
  3171.       IF RET THEN _
  3172.          GOTO 58309
  3173.       IF LINES.PRINTED < FF THEN _
  3174.          GOTO 58304
  3175.       CALL CARRIER
  3176.       IF NOT LOCAL.USER AND SUBROUTINE.PARAMETER = -1 THEN _
  3177.          GOTO 58309
  3178.       IF NON.STOP THEN _
  3179.          GOTO 58304
  3180.       IF STOP.INTERRUPTS THEN _
  3181.          A$ = "MORE: [Y],N,NS" _
  3182.       ELSE _
  3183.          A$ = "Press [ENTER] to continue"
  3184.       LINES.PRINTED = 0
  3185.       SUBROUTINE.PARAMETER = 1
  3186.       NO.ADVANCE = TRUE
  3187.       CALL TGET
  3188.       CALL WIPELINE (26)
  3189.       IF NO THEN _
  3190.          IF STOP.INTERRUPTS THEN _
  3191.             GOTO 58309
  3192. 58304 START.BYTE = EOD + EOL.LEN
  3193.       IF START.BYTE <= DATA.SIZE THEN _
  3194.          GOTO 58301
  3195.       EXIT SUB
  3196. 58309 'Common ABORT routine
  3197.       STOP.FILE = TRUE
  3198.       END SUB
  3199. ' $SUBTITLE: 'BUFFILE - subroutine to write a sequential file to the user'
  3200. ' $PAGE
  3201. '
  3202. '  SUBROUTINE NAME    -- BUFFILE
  3203. '
  3204. '  INPUT PARAMETERS   -- PARAMETER                      MEANING
  3205. '                        FILENAME$               NAME OF THE FILE TO WRITE TO
  3206. '                                                OUT TO THE USER
  3207. '
  3208. '  OUTPUT PARAMETERS  -- NONE                    FILE IS WRITTEN TO THE USER
  3209. '
  3210. '  SUBROUTINE PURPOSE -- TO DISPLAY A SEQUENTIAL FILE TO THE USER
  3211. '
  3212. 58400 SUB BUFFILE (FILNAME$) STATIC
  3213.       CALL FINDIT (FILNAME$)
  3214.       IF NOT OK THEN _
  3215.          EXIT SUB
  3216.       CALL OPENRSEQ (FILNAME$,NUM.RECS,LEN.LAST.REC)
  3217.       DATA.SIZE = BUFFER.SIZE
  3218.       FIELD 2, DATA.SIZE AS SEQ.REC$
  3219.       NON.STOP = (PAGE.LENGTH < 1)
  3220.       STOP.FILE = FALSE
  3221.       IF STOP.INTERRUPTS THEN _
  3222.          A$ = "* <Ctrl K>/<Ctrl X> aborts <Ctrl S> suspends *" : _
  3223.          SUBROUTINE.PARAMETER = 2 : _
  3224.          CALL TPUT
  3225.       TU = 0
  3226. 58405 TU = TU + 1
  3227.       IF TU < NUM.RECS THEN_
  3228.          GET 2,TU _
  3229.       ELSE IF TU = NUM.RECS THEN _
  3230.               GET 2,TU : _
  3231.               X = INSTR(SEQ.REC$,CHR$(26)) :_
  3232.               IF X=0 OR X > LEN.LAST.REC THEN _
  3233.                  DATA.SIZE = LEN.LAST.REC _
  3234.               ELSE DATA.SIZE = X-1 _
  3235.            ELSE GOTO 58419
  3236.       IF (NOT STOP.INTERRUPTS) THEN _
  3237.          CALL BUFSTRNG (SEQ.REC$,DATA.SIZE)_
  3238.       ELSE IF LOCAL.USER THEN _
  3239.               CALL BUFSTRNG (SEQ.REC$,DATA.SIZE)_
  3240.       ELSE IF EOF(3) THEN _
  3241.               CALL BUFSTRNG (SEQ.REC$,DATA.SIZE)_
  3242.       ELSE _
  3243.           A$ = LEFT$(SEQ.REC$,DATA.SIZE) : _
  3244.           SUBROUTINE.PARAMETER = 4 : _
  3245.           CALL TPUT : _
  3246.           IF SUBROUTINE.PARAMETER = -1 OR RET THEN _
  3247.              GOTO 58419
  3248.       CALL TIMEREMAIN (TIME.REMAINING!)
  3249.       IF TIME.REMAINING! < 0.1 THEN _
  3250.          GOTO 58419
  3251.       IF NOT STOP.FILE THEN _
  3252.          GOTO 58405
  3253. 58419 CLOSE 2
  3254.       NON.STOP = (PAGE.LENGTH < 1)
  3255.       END SUB
  3256. ' $SUBTITLE: 'FINDLAST - subroutine to find last occurence of a string'
  3257. ' $PAGE
  3258. '
  3259. '  SUBROUTINE NAME    -- FINDLAST
  3260. '
  3261. '  INPUT PARAMETERS   -- PARAMETER             MEANING
  3262. '                        LOOK.IN$           STRING TO LOOK INTO
  3263. '                        LOOK.FOR$          STRING TO SEARCH FOR
  3264. '
  3265. '  OUTPUT PARAMETERS  -- WHERE.FOUND        POSITION IN LOOK.IN$ THAT
  3266. '                                            LOOK.FOR$ FOUND
  3267. '                        NUM.FINDS          HOW MANY OCCURENCES IN LOOK.IN$
  3268. '
  3269. '  SUBROUTINE PURPOSE -- Finds last occurence of LOOK.FOR$ in LOOK.IN$ and
  3270. '                        returns count of # of occurences.  If none found,
  3271. '                        both returned parms are 0.
  3272. '
  3273.       SUB FINDLAST (LOOK.IN$,LOOK.FOR$,WHERE.FOUND,NUM.FINDS) STATIC
  3274. 58600 WHERE.FOUND = INSTR(LOOK.IN$,LOOK.FOR$)
  3275.       NUM.FINDS = -(WHERE.FOUND > 0)
  3276.       NEXT.FOUND = INSTR(WHERE.FOUND+1,LOOK.IN$,LOOK.FOR$)
  3277.       WHILE NEXT.FOUND > 0
  3278.         NUM.FINDS = NUM.FINDS + 1
  3279.         WHERE.FOUND = NEXT.FOUND
  3280.         NEXT.FOUND = INSTR(WHERE.FOUND+1,LOOK.IN$,LOOK.FOR$)
  3281.       WEND
  3282.       END SUB
  3283. ' $SUBTITLE: 'ROTORSDIR - search thru a list of subdirs for a file'
  3284. ' $PAGE
  3285. '
  3286. '  SUBROUTINE NAME    -- ROTORSDIR
  3287. '
  3288. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  3289. '                        FILNAME$                  FILE NAME TO LOOK FOR
  3290. '                        SDIR.ARA                  ARRAY OF SUBDIRECTORIES
  3291. '                        MAX.SEARCH                MAX # OF SUBDIRECTORIES
  3292. '
  3293. '   OUTPUT PARAMETERS -- FNAME$                    ADD SUBDIRECTORY TO THE
  3294. '                                                  FILE NAME IF FOUND.  OTHER-
  3295. '                                                  WISE DON'T.
  3296. '                        OK                        TRUE IF FILE WAS FOUND
  3297. '
  3298. '  SUBROUTINE PURPOSE -- HUNT THROUGH A LIST OF SUBDIRECTORIES TO DETERMINE
  3299. '                        IF A FILE IS IN ANY OF THEM.  IF FILE IS FOUND, OPEN
  3300. '                        THE FILE AS FILE #2, ADD THE DRIVE/PATH TO THE FILE
  3301. '                        NAME, AND SETS OK TO TRUE.  IF FILE ISN'T FOUND, SET
  3302. '                        FILE NAME TO THE LAST SUBDIRECTORY SEARCHED -- WHICH
  3303. '                        SHOULD BE THE UPLOAD SUBDIRECTORY.
  3304. '
  3305.       SUB ROTORSDIR (FILNAME$,SDIR.ARA$(1),MAX.SEARCH) STATIC
  3306. 58700 OK = FALSE
  3307.       NUM.SEARCH = 1
  3308.       WHILE (NOT OK) AND NUM.SEARCH <= MAX.SEARCH AND_
  3309.         SDIR.ARA$(NUM.SEARCH)<>""
  3310.           X$ = SDIR.ARA$(NUM.SEARCH) + FILNAME$
  3311.           CALL FINDIT (X$)
  3312.           NUM.SEARCH = NUM.SEARCH + 1
  3313.       WEND
  3314.       FILNAME$ = X$
  3315.       END SUB
  3316. ' $SUBTITLE: 'WIPELINE - Wipe away a line so next overprints'
  3317. ' $PAGE
  3318. '
  3319. '  SUBROUTINE NAME    -- WIPELINE
  3320. '
  3321. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  3322. '                            CARRIAGE.RETURN$
  3323. '                            CHARS.TO.WIPE            # OF CHARACTERS TO BLANK
  3324. '                            NULLS
  3325. '
  3326. '   OUTPUT PARAMETERS -- NONE
  3327. '
  3328. '  SUBROUTINE PURPOSE -- WIPE AWAY A LINE AND LEAVE CURSOR AT BEGINNING OF THE
  3329. '                        SAME LINE SO THAT THE NEXT LINE WILL PRINT IN ITS
  3330. '                        PLACE
  3331. '
  3332.       SUB WIPELINE (CHARS.TO.WIPE) STATIC
  3333. 58800 IF NULLS THEN _
  3334.          CALL SKIPLINE (1) : _
  3335.          EXIT SUB
  3336.       IF NOT LOCAL.USER THEN _
  3337.          PRINT #3,CARRIAGE.RETURN$;SPACE$(CHARS.TO.WIPE);CARRIAGE.RETURN$
  3338.       IF SNOOP THEN _
  3339.          LOCATE ,1 :  _
  3340.          PRINT SPACE$(CHARS.TO.WIPE); : _
  3341.          LOCATE ,1
  3342.       END SUB
  3343. ' $SUBTITLE: 'GETDIRS -- Prompt for directories to search'
  3344. ' $PAGE
  3345. '
  3346. '  SUBROUTINE NAME    -- GETDIRS
  3347. '
  3348. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  3349. '                             STRNG$                  OPTION TO ADD IN PROMPT
  3350. '                                                     TO EXPLAIN ENTER
  3351. '                             DIR.PROMPT$             BASE OF DIRECTORY PROMPT
  3352. '
  3353. '   OUTPUT PARAMETERS --     B$
  3354. '                            Q
  3355. '  SUBROUTINE PURPOSE -- Prompt for directories to search
  3356. '
  3357.       SUB GETDIRS (STRNG$) STATIC
  3358. 58900 A$ = DIR.PROMPT$ + STRNG$ + ")"
  3359.       SUBROUTINE.PARAMETER = 1
  3360.       CALL TGET
  3361.       IF Q = 0 OR SUBROUTINE.PARAMETER = -1 THEN _
  3362.          EXIT SUB
  3363.       IF INSTR("Hh",B$(1)) THEN _
  3364.          CALL BUFFILE (DIRECTORY.PATH$+DIRECTORY.EXTENTION$+_
  3365.                       "."+DIRECTORY.EXTENTION$):_
  3366.          GOTO 58900
  3367.       END SUB
  3368. '
  3369. ' $SUBTITLE: 'CONVDIRS -- Converts coded response to right directory'
  3370. ' $PAGE
  3371. '
  3372. '  SUBROUTINE NAME    -- CONVDIRS
  3373. '
  3374. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  3375. '                            STRT               ELEMENT TO BEGIN WITH
  3376. '                            B$                 ARRAY TO CONVERT
  3377. '                            Q                  LAST ELEMENT TO CONFERT
  3378. '
  3379. '   OUTPUT PARAMETERS --     B$                 CONVERTED DIRECTORY LIST
  3380. '
  3381. '  SUBROUTINE PURPOSE -- LET THE USER PUT IN A SHORT STANDARD STRING FOR A
  3382. '                        DIRECTORY
  3383. '
  3384. '
  3385. 58950 SUB CONVDIRS (STRT) STATIC
  3386.       FOR I=STRT TO Q
  3387.           CALL ALLCAPSD(B$(),I)
  3388.           IF B$(I)="U" THEN _
  3389.              B$(I) = UPLOAD.DIR.CHECK$
  3390.           IF B$(I) = "A" THEN _
  3391.              B$(I) = "ALL"
  3392.           IF B$(I) = "ALL" THEN _
  3393.              IF MASTER.DIRECTORY.NAME$ <> "" THEN _
  3394.                 B$(I) = MASTER.DIRECTORY.NAME$ : _
  3395.                 IF USER.SECURITY.LEVEL >= MIN.SEC.TO.VIEW THEN _
  3396.                    Q = Q + 1 : _
  3397.                    B$(Q) = UPLOAD.DIR.CHECK$
  3398.       NEXT
  3399.       END SUB
  3400. ' $SUBTITLE: 'MUSIC - subroutine to PLAY MUSIC'
  3401. ' $PAGE
  3402. '
  3403. '  SUBROUTINE NAME    -- MUSIC
  3404. '
  3405. '  INPUT PARAMETERS   --   PARAMETER     MEANING
  3406. '                                 1   PLAY CONSIDER YOURSELF(OPENING SCREEN)
  3407. '                                 2   PLAY WALK RIGHT IN(NEW USERS)
  3408. '                                 3   PLAY DRAGNET (SECURITY VIOLATION)
  3409. '                                 4   PLAY GOODBYE CHARLIE (GOODBYE)
  3410. '                                 5   PLAY TAPS (ACCESS DENIED)
  3411. '                                 6   PLAY OOM PAH PAH (DOWNLOAD)
  3412. '                                 7   PLAY THNKS FOR MEMORIES(UPLOAD)
  3413. '
  3414. '  OUTPUT PARAMETERS  -- NONE
  3415. '
  3416. '  SUBROUTINE PURPOSE -- PROVIDE SYSOP'S AND THE VISUALLY IMPARED WITH
  3417. '                        AUDITORY FEEDBACK ON WHAT RBBS-PC IS DOING
  3418. '
  3419.       SUB MUSIC (PASSED.ARG) STATIC
  3420. 59100 FF = PASSED.ARG
  3421.       SUBROUTINE.PARAMETER = 0
  3422.       IF (NOT MUSIC) OR LOCAL.USER.MODE THEN _
  3423.          EXIT SUB
  3424.       ON FF GOTO 59102,59104,59106,59108,59110,59112,59114
  3425.       EXIT SUB
  3426. 59102 '---[Introduction CONSIDER YOURSELF]---
  3427.     LEC$ = "MBT180A4B-8B-8B-8B-2.G4A8F2"
  3428.     PLAY "O2 X" + VARPTR$(LEC$)
  3429.     EXIT SUB
  3430. 59104 '---[New User WALK RIGHT IN]---
  3431.     LEC1$ = "MBT180G4G4D2G8F+8F8E2A8B8":LEC2$="C8C+8D8C8":LEC3$="B4G2"
  3432.     PLAY "O2 X"+VARPTR$(LEC1$)+"O3 X"+VARPTR$(LEC2$)+"O2 X"+VARPTR$(LEC3$)
  3433.     EXIT SUB
  3434. 59106 '---[Security Violation DRAGNET THEME]---
  3435.      LEC$ = "MBT120C2D8E-4C2.C2D8E-4C4G-2."
  3436.      PLAY "O2 X" + VARPTR$(LEC$)
  3437.      EXIT SUB
  3438. 59108 '---[Goodbye GOODBYE CHARLIE]---
  3439.       LEC$ = "MBT180B-2.G2.F4D2."
  3440.       PLAY "O2 X" + VARPTR$(LEC$)
  3441.       EXIT SUB
  3442. 59110 '---[Access Denied TAPS]---
  3443.       LEC1$ = "MBT90F8A16":LEC2$="C4.":LEC3$="A4F4C2.C8C16F2"
  3444.       PLAY "O2 X"+VARPTR$(LEC1$)+"O3 X"+VARPTR$(LEC2$)+"O2 X"+VARPTR$(LEC3$)
  3445.       EXIT SUB
  3446. 59112 '---[Download OOM PAH PAH]---
  3447.        LEC$ = "MBT180F4A4A4C4A4A4G4A4G4D2"
  3448.        PLAY "O2 X" + VARPTR$(LEC$)
  3449.        EXIT SUB
  3450. 59114 '---[Upload THANKS FOR THE MEMORIES]---
  3451.        LEC1$ = "MBT180C2." :LEC2$ = "A8G8F4D2"
  3452.        PLAY "O3 X" + VARPTR$(LEC1$)+ "O2 X" + VARPTR$(LEC2$)
  3453.        END SUB
  3454. ' $SUBTITLE: 'TWOBYTEDATE -- subroutine to put date in two bytes'
  3455. ' $PAGE
  3456. '
  3457. '  SUBROUTINE NAME    -- TWOBYTEDATE
  3458. '
  3459. '  INPUT PARAMETERS   --   PARAMETER     MEANING
  3460. '                             YY       FOUR DIGIT YEAR (I.E. 1987)
  3461. '                             MM       MONTH
  3462. '                             DD       DAY
  3463. '                           RESULT$    LOCATION TO PLACE THE RESULT
  3464. '
  3465. '  OUTPUT PARAMETERS  -- RESULT$       TWO BYTE COMPRESSED DATE FOR USE IN
  3466. '                                      A RANDOM RECORD
  3467. '
  3468. '  SUBROUTINE PURPOSE -- COMPRESS AN 8-CHARACTER DATE INTO TWO CHARACTERS
  3469.       SUB TWOBYTEDATE (YY,MM,DD,RESULT$) STATIC
  3470. 59200 RESULT$ = CHR$(((YY-1980)*2) OR -((MM AND 8)<>0)) + _
  3471.                 CHR$((MM AND NOT 8)*32+DD)
  3472.       END SUB
  3473. ' $SUBTITLE: 'GETYMD -- subroutine to unpack a two-byte date'
  3474. ' $PAGE
  3475. '
  3476. '  SUBROUTINE NAME    -- GETYMD
  3477. '
  3478. '  INPUT PARAMETERS   --   PARAMETER     MEANING
  3479. '                          TWOBYTE$    PACKED TWO-BYTE DATE FIELD
  3480. '                            YMD       1 = YEAR
  3481. '                                      2 = MONTH
  3482. '                                      3 = DAY
  3483. '                           RESULT     LOCATION TO PLACE THE RESULT
  3484. '
  3485. '  OUTPUT PARAMETERS  -- RESULT        FOUR DIGIT RESULT OF UNPAKING THE DATE
  3486. '
  3487. '  SUBROUTINE PURPOSE -- UNPACK A COMPRESSED TWO-BYTE DATE FIELD
  3488. '
  3489.       SUB GETYMD (TWOBYTE$,YMD,RESULT) STATIC
  3490.       ON YMD GOTO 59205,59210,59215
  3491.       EXIT SUB
  3492. 59205 RESULT = (ASC(TWOBYTE$)AND NOT 1)/2 + 1980
  3493.       EXIT SUB
  3494. 59210 RESULT = FIX((ASC(MID$(TWOBYTE$,2))/32))OR((ASC(TWOBYTE$)AND 1)*8)
  3495.       EXIT SUB
  3496. 59215 RESULT = ASC(MID$(TWOBYTE$,2))AND NOT 224
  3497.       END SUB
  3498. ' $SUBTITLE: 'COMPDATE -- subroutine to compute elased days'
  3499. ' $PAGE
  3500. '
  3501. '  SUBROUTINE NAME    -- COMPDATE
  3502. '
  3503. '  INPUT PARAMETERS   --   PARAMETER     MEANING
  3504. '                            YY        YEAR
  3505. '                            MM        MONTH
  3506. '                            DD        DAY
  3507. '                           RESULT!    LOCATION TO PLACE THE RESULT
  3508. '
  3509. '  OUTPUT PARAMETERS  -- RESULT!       COMPUTE COMPUTATIONAL DATE
  3510. '
  3511. '  SUBROUTINE PURPOSE -- COMPUTES A COMPUTATIONAL DATE FROM YEAR, MONTH, DAY.
  3512. '                        RESULTS MAY BE USED TO COMPUTE THE NUMBER OF ELASPED
  3513. '                        DAYS BETWEEN TWO DATES.  YOU MAY PASS A 2 OR 4 DIGIT
  3514. '                        YEAR, BUT FOR MEANINGFUL RESULTS, BE CONSISTENT
  3515. '
  3516.       SUB COMPDATE (YY,MM,DD,RESULT!) STATIC
  3517.       RESULT! = YY*365.0 + _
  3518.                 INT((YY-1)/4) + _
  3519.                 (MM-1)*28 + _
  3520.                 VAL(MID$("000303060811131619212426",(MM-1)*2+1,2)) - _
  3521.                 ((MM>2)AND((YY MOD 4)=0)) + _
  3522.                 DD
  3523.       END SUB
  3524. ' $SUBTITLE: 'PROTOCOL - check for external protocols'
  3525. ' $PAGE
  3526. '
  3527. '  SUBROUTINE NAME    -- PROTOCOL
  3528. '
  3529. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  3530. '                        TRANSFER.OPTIONS$         FILE TRANSFER PROTOCOLS
  3531. '                                                  THAT ARE ALLOWED.
  3532. '
  3533. '   OUTPUT PARAMETERS -- PCKERMIT.EXE.FILE$        FILE TO TRANSFER CONTROL TO
  3534. '                                                  FOR KERMIT PROTOCOL
  3535. '                        KERMIT.SUPPORT            SWITCH INDICATING KERMIT IS
  3536. '                                                  AVAILABLE
  3537. '                        XFER.COM.FILE$            FILE TO TRANSFER CONTROL TO
  3538. '                                                  FOR YMODEM, IMODEM & YMODEMG
  3539. '                        XFER.SUPPORT              SWITCH INDICATING THAT
  3540. '                                                  YMODEM, IMODEM & YMODEMG
  3541. '                                                  ARE AVAILABLE
  3542. '                        WXMODEM.COM.FILE$         FILE TO TRANSFER CONTROL TO
  3543. '                                                  FOR WXMODEM SUPPORT
  3544. '                        WXMODEM.SUPPORT           SWITCH INDICATING THAT
  3545. '                                                  WXMODEM IS AVAILABLE
  3546. '
  3547. '  SUBROUTINE PURPOSE -- TO DETERMINE IF EXTERNAL PROTOCOL'S ARE AVAILABLE
  3548. '
  3549.       SUB PROTOCOL STATIC
  3550. 62600 XFER.SUPPORT = TRUE
  3551.       WXMODEM.SUPPORT = TRUE
  3552.       KERMIT.SUPPORT = TRUE
  3553.       WXMODEM.COM.FILE$ = PROTOCOL.PATH$ + "WXMODEM.COM"
  3554.       CALL FINDIT (WXMODEM.COM.FILE$)
  3555.       IF NOT OK THEN _
  3556.          TRANSFER.OPTIONS$ = LEFT$(TRANSFER.OPTIONS$,71) + _
  3557.                              MID$(TRANSFER.OPTIONS$,82) : _
  3558.          WXMODEM.SUPPORT = FALSE
  3559.       XFER.COM.FILE$ = PROTOCOL.PATH$ + "QMXFER.COM"
  3560.       CALL FINDIT (XFER.COM.FILE$)
  3561.       IF NOT OK THEN _
  3562.          TRANSFER.OPTIONS$ = LEFT$(TRANSFER.OPTIONS$,42) + _
  3563.                              MID$(TRANSFER.OPTIONS$,72) : _
  3564.          XFER.SUPPORT = FALSE
  3565.       KERMIT.EXE.FILE$ = PROTOCOL.PATH$ + "PCKERMIT.EXE"
  3566.       CALL FINDIT (KERMIT.EXE.FILE$)
  3567.       IF NOT OK THEN _
  3568.          TRANSFER.OPTIONS$ = LEFT$(TRANSFER.OPTIONS$,33) + _
  3569.                              MID$(TRANSFER.OPTIONS$,43) : _
  3570.          KERMIT.SUPPORT = FALSE
  3571.       CLOSE 2
  3572.       IF KERMIT.SUPPORT = 0 AND _
  3573.          XFER.SUPPORT = 0 AND _
  3574.          WXMODEM.SUPPORT = 0 THEN _
  3575.          TRANSFER.OPTIONS$ = LEFT$(TRANSFER.OPTIONS$,31) + _
  3576.                              MID$(TRANSFER.OPTIONS$,34)
  3577.       END SUB
  3578. ' $SUBTITLE: 'TRANSFER - subroutine for KERMIT, YMODEM, IMODEM & YMODEM'
  3579. ' $PAGE
  3580. '
  3581. '  SUBROUTINE NAME    -- TRANSFER
  3582. '
  3583. '  INPUT PARAMETERS   --     PARAMETER                    MEANING
  3584. '                        TRANSFER.FUNCTION         = 1 DOWNLOAD FILE TO USER
  3585. '                                                  = 2 UPLOAD FILE TO RBBS-PC
  3586. '                        FILE.NAME$                NAME OF FILE FOR TRANSFER
  3587. '                        COM.PORT$                 NAME OF COMMUNICATIONS PORT
  3588. '                                                  TO BE USED BY KERMIT (COM1
  3589. '                                                  OR COM2)
  3590. '                        BPS                       = -1 FOR   300 BAUD
  3591. '                                                  = -2 FOR   450 BAUD
  3592. '                                                  = -3 FOR  1200 BAUD
  3593. '                                                  = -4 FOR  2400 BAUD
  3594. '                                                  = -5 FOR  4800 BAUD
  3595. '                                                  = -6 FOR  9600 BAUD
  3596. '                        PCKERMIT.EXE.FILE$        FILE TO TRANSFER CONTROL TO
  3597. '                                                  FOR KERMIT PROTOCOL ON
  3598. '                                                  PROTOCOL.PATH$.
  3599. '                        QMXFER.COM.FILE$          FILE TO TRANSFER CONTROL TO
  3600. '                                                  FOR YMODEM, IMODEM OR
  3601. '                                                  YMODEMG PROTOCOLS.
  3602. '                        WXMODEM.COM.FILE$         FILE TO TRANSFER CONTROL TO
  3603. '                                                  FOR WXMODEM PROTOCOL ON
  3604. '                                                  PROTOCOL.PATH$
  3605. '
  3606. '  OUTPUT PARAMETERS  -- NONE
  3607. '
  3608. '  SUBROUTINE PURPOSE -- TO TRANSFER FILES USING KERMIT, YMODEM, IMODEM,
  3609. '                        YMODEMG OR WXMODEM PROTOCOL'S
  3610. '
  3611. 62620 SUB TRANSFER STATIC
  3612.       IF PRIVATE.DOOR THEN _
  3613.          GOTO 62629
  3614.       IF TRANSFER.FUNCTION = 1 THEN _
  3615.          TRANSFER.COMMAND$ = "-s " : _
  3616.          A$ = " send of " _
  3617.       ELSE IF TRANSFER.FUNCTION = 2 THEN _
  3618.               TRANSFER.COMMAND$ = "-r ": _
  3619.               A$ = " receive of " : _
  3620.               IF FF = 4 THEN _
  3621.                  TRANSFER.COMMAND$ = TRANSFER.COMMAND$ + _
  3622.                                      "-a "
  3623.       IF FF <> 4 THEN _
  3624.          TRANSFER.COMMAND$ = TRANSFER.COMMAND$ + "-f "
  3625.       TRANSFER.COMMAND$ = TRANSFER.COMMAND$ + _
  3626.                           FILE.NAME$ + _
  3627.                           " -l " + COM.PORT$ + _
  3628.                           " -c" + _                 ' CARRIER DROP
  3629.                           " -b " + _                ' LINE SPEED
  3630.                           MID$("    300 4501200240048009600",(-4*BPS),4)
  3631.       IF FF = 4 THEN _
  3632.          TRANSFER.COMMAND$ = TRANSFER.COMMAND$ + _
  3633.                              " -p n" + _            ' PARITY = NONE
  3634.                              " -m 31" _             ' PACKETS
  3635.       ELSE TRANSFER.COMMAND$ = TRANSFER.COMMAND$ + _
  3636.                                " -p " + _
  3637.                                MID$("AXCKYIGW",FF,1) + _
  3638.                                " -n " + _
  3639.                                NODE.ID$
  3640.       ON FF GOTO 62628, _     ' 1 = ASCII FILE TRANSFER
  3641.                  62622, _     ' 2 = XMODEM (CHECKSUM) FILE TRANSFER
  3642.                  62622, _     ' 3 = XMODEM (CRC-16) FILE TRANSFER
  3643.                  62624, _     ' 4 = KERMIT FILE TRANSFER
  3644.                  62622, _     ' 5 = YMODEM FILE TRANSFER
  3645.                  62622, _     ' 6 = IMODEM FILE TRANSFER
  3646.                  62622, _     ' 7 = YMODEMG FILE TRANSFER
  3647.                  62626        ' 8 = WXMODEM FILE TRANSFER
  3648. 62622 B$ = "QMXFER"
  3649.       IF FF<4 THEN _
  3650.          Y$ = "XMODEM ":_
  3651.          IF FF=2 THEN _
  3652.             Y$ = Y$ + "(CHECKSUM)"_
  3653.          ELSE_
  3654.             Y$ = Y$ + "(CRC-16)"_
  3655.       ELSE_
  3656.          IF FF=6 THEN_
  3657.             Y$ = "IMODEM"_
  3658.          ELSE_
  3659.             Y$ = "YMODEM":_
  3660.             IF FF=7 THEN _
  3661.                Y$ = Y$ + "G"
  3662.       GOTO 62628
  3663. 62624 B$ = "PCKERMIT"
  3664.       Y$ = "KERMIT"
  3665.       GOTO 62628
  3666. 62626 B$ = "WXMODEM"
  3667.       Y$ = "XMODEM (WINDOWED)"
  3668. 62628 CLOSE 2
  3669.       OPEN NODE.WORK.FILE$ FOR OUTPUT AS #2
  3670.       B$ = PROTOCOL.PATH$ + B$ + " " + TRANSFER.COMMAND$
  3671.       PRINT #2,B$
  3672.       CLOSE 2
  3673.       CALL QTPUT (Y$ + A$ + FILE.NAME.HOLD$ + " ready!",1)
  3674.       IF GO.TO.SHELL THEN _
  3675.          GOTO 62629
  3676.       A$(1) = DISK.FOR.DOS$ + "COMMAND /C " + B$
  3677.       A$(2) = RBBS.BAT$
  3678.       PRIVATE.DOOR = TRUE
  3679.       CALL RBBSEXIT (A$(),2)
  3680. 62629 CLOSE 3
  3681.       OUT MODEM.CONTROL.REGISTER,INP(MODEM.CONTROL.REGISTER) OR 1
  3682.       IF PRIVATE.DOOR THEN _
  3683.          PRIVATE.DOOR = FALSE : _
  3684.          GOTO 62630
  3685.       CALL DELAYIT (2)
  3686.       SHELL NODE.WORK.FILE$
  3687. 62630 COM.PORT.INFO$ = COM.PORT$ + ":" + _
  3688.                        MID$("    300 4501200240048009600",(-4*BPS),4) + "," + _
  3689.                        MID$("N,8,1E,7,1",6 + 5*EIGHT.BIT,5) + _
  3690.                        ",RS,CD,DS"
  3691.       IF LOCAL.USER THEN _
  3692.          GOTO 62631
  3693.       OPEN COM.PORT.INFO$ AS # 3
  3694.       CALL SKIPLINE (1)
  3695. 62631 IF TRANSFER.FUNCTION = 2 AND _
  3696.          FF = 4 THEN _
  3697.      CLS : _
  3698.          CALL LINE25
  3699. 62632 END SUB
  3700. ' $SUBTITLE: 'VIEWARC - subroutine to display .ARC contents'
  3701. ' $PAGE
  3702. '
  3703. '  SUBROUTINE NAME    --  VIEWARC  (Written by Jon Martin)
  3704. '
  3705. '  INPUT PARAMETERS   --  PARAMETER                   MEANING
  3706. '                         FILE.NAME$           NAME OF THE ARC FILE TO BE
  3707. '                                              VIEWED.
  3708. '
  3709. '  OUTPUT PARAMETERS  --  NONE
  3710. '
  3711. '  SUBROUTINE PURPOSE --  PROVIDES A MECHANISM TO PROVIDE USERS WITH THE
  3712. '                         CONTENTS OF AN ARC FILE PRIOR TO DOWNLOADING.
  3713.       SUB VIEWARC STATIC
  3714. 64600 IF TURBO.RBBS THEN _
  3715.          RETCODE% = 0 : _
  3716.          CALL ARCV (ARC.WORK$,FILE.NAME$,RETCODE%) : _
  3717.          CALL BUFFILE (ARC.WORK$) : _
  3718.          EXIT SUB
  3719.       CLOSE 2
  3720.       OPEN "R",2,FILE.NAME$,1
  3721.       FIELD 2,1 AS CHAR$
  3722.       BYTE.POINTER! = 1
  3723.       ARC.END! = LOF(2)
  3724. 64605 IF BYTE.POINTER! > ARC.END! THEN _
  3725.          GOTO 64620
  3726.       GET 2,BYTE.POINTER!
  3727.       IF CHAR$ <> CHR$(26) THEN _
  3728.          GOTO 64620
  3729.       BYTE.POINTER! = BYTE.POINTER! +1
  3730.       GET 2,BYTE.POINTER!
  3731.       IF CHAR$ = CHR$(0) THEN _
  3732.          GOTO 64620
  3733.       ARCED.NAME$ = ""
  3734.       FOR X = 1 TO 12
  3735.       GET 2,BYTE.POINTER! + X
  3736.       IF CHAR$ < CHR$(40) THEN _
  3737.          GOTO 64610
  3738.       ARCED.NAME$ = ARCED.NAME$ + CHAR$
  3739.       NEXT
  3740. 64610 A$ = ARCED.NAME$
  3741.       BYTE.POINTER! = BYTE.POINTER! + 14
  3742.       GOSUB 64630
  3743.       TOTAL.BYTES# = WORK.BYTES#
  3744.       BYTE.POINTER! = BYTE.POINTER! + 10
  3745.       GOSUB 64630
  3746.       FINAL.BYTES# = WORK.BYTES#
  3747.       A$ = A$ + SPACE$(20-LEN(ARCED.NAME$) - LEN(STR$(FINAL.BYTES#))) _
  3748.               + STR$(FINAL.BYTES#) _
  3749.               + " bytes."
  3750.       CALL QTPUT(A$,1)
  3751.       BYTE.POINTER! = BYTE.POINTER! + TOTAL.BYTES# + 4
  3752.       GOTO 64605
  3753. 64620 CLOSE 2
  3754.       SUBROUTINE.PARAMETER = 0
  3755.       CALL CARRIER
  3756.       A$ = ""
  3757.       EXIT SUB
  3758. 64630 FACTOR# = 1#
  3759.       WORK.BYTES# = 0
  3760.       FOR X = 0 TO 3
  3761.           GET 2,BYTE.POINTER! + X
  3762.           WORK.BYTES# = WORK.BYTES# + FACTOR# * ASC(CHAR$)
  3763.           FACTOR# = FACTOR# * 256#
  3764.       NEXT
  3765.       RETURN
  3766.       END SUB
  3767.